4

我尝试调整我的查询,但我不知道我可以改变什么:

  • 两张表的截图:http ://abload.de/image.php?img=1plkyg.jpg
  • 关系是:1 个 UserPM(私人消息)有 1 个发件人(用户,SenderID -> User.SenderID)和 1 个收件人(用户,RecipientID -> User.UserID),1 个用户有 X 个 UserPM 作为收件人,X 个 UserPM 作为发件人.
  • 初始加载大约需要 200 毫秒,它只需要前 20 行并显示它们。显示后,JavaScript PageMethod 获取GetAllPMsAsReciepient方法并加载其余数据
  • GetAllPMsAsReciepient方法每次运行大约 250 行大约需要 4.5 到 5.0 秒

我的代码:

    public static List<UserPM> GetAllPMsAsReciepient(Guid userID)
    {
        using (RPGDataContext dc = new RPGDataContext())
        {
            DateTime dt = DateTime.Now;

            DataLoadOptions options = new DataLoadOptions();
            //options.LoadWith<UserPM>(a => a.User);
            options.LoadWith<UserPM>(a => a.User1);
            dc.LoadOptions = options;

            List<UserPM> pm = (
                      from a in dc.UserPMs 
                      where a.RecieverID == userID 
                      && !a.IsDeletedRec 
                      orderby a.Timestamp descending select a
            ).ToList();

            TimeSpan ts = DateTime.Now - dt;
            System.Diagnostics.Debug.WriteLine(ts.Seconds + "." + ts.Milliseconds);

            return pm;
        }
    }

我不知道如何调整这个查询,我的意思是 250 个 PM 根本不算什么,在其他网站上的其他收件箱上,我收到了大约 5000 个或其他东西,而且它不需要一秒钟来加载......

我尝试在时间戳上设置索引以减少Orderby时间,但到目前为止没有发生任何事情。

这里有什么想法吗?

编辑

我尝试在 LinqPad 上重现它:没有 DataLoadOptions,在 LinqPad 中查询需要 300 毫秒,DataLoadOptions 大约需要 1 秒。

所以,这意味着:

  • 如果我可以避免在此查询中加载用户表,我可以节省大约 60% 的时间,但是如何?
  • 为什么 Linqpad 在同一连接上只需要 1 秒,来自同一台计算机,而我的代码需要 4.5-5.0 秒?
  • 这是执行计划:http ://abload.de/image.php?img=54rjwq.jpg
  • 这是 SQL Linqpad 给我的:

选择 [t0].[PMID], [t0].[Text], [t0].[RecieverID], [t0].[SenderID], [t0].[Title], [t0].[Timestamp], [ t0].[IsDeletedRec], [t0].[IsRead], [t0].[IsDeletedSender], [t0].[IsAnswered], [t1].[UserID], [t1].[Username], [t1] .[密码], [t1].[Email], [t1].[RegisterDate], [t1].[LastLogin], [t1].[RegisterIP], [t1].[RefreshPing], [t1].[ Admin], [t1].[IsDeleted], [t1].[DeletedFrom], [t1].[IsBanned], [t1].[BannedReason], [t1].[BannedFrom], [t1].[BannedAt] , [t1].[NowPlay], [t1].[AcceptAGB], [t1].[AcceptRules], [t1].[MainProfile], [t1].[SetShowHTMLEditorInRPGPosts], [t1].[Age], [ t1].[SetIsAgePublic], [t1].[City], [t1].[SetIsCityShown], [t1].[Verified], [t1].[Design], [t1].[SetRPGCountPublic], [t1] .[SetLastLoginPublic], [t1].[SetRegisterDatePublic], [t1].[SetGBActive], [t1].[Gender], [t1].[IsGenderVisible], [t1].[OnlinelistHidden], [t1].[生日],[t1]。[SetIsMenuHideable]、[t1].[SetColorButtons]、[t1].[SetIsAboutMePublic]、[t1].[Name]、[t1].[SetIsNamePublic]、[t1].[ContactAnimexx]、[t1].[ContactRPGLand ], [t1].[ContactSkype], [t1].[ContactICQ], [t1].[ContactDeviantArt], [t1].[ContactFacebook], [t1].[ContactTwitter], [t1].[ContactTumblr], [t1].[IsContactAnimexxPublic], [t1].[IsContactRPGLandPublic], [t1].[IsContactSkypePublic], [t1].[IsContactICQPublic], [t1].[IsContactDeviantArtPublic], [t1].[IsContactFacebookPublic], [t1 ].[IsContactTwitterPublic], [t1].[IsContactTumblrPublic], [t1].[IsAdult], [t1].[IsShoutboxVisible], [t1].[Notification], [t1].[ShowTutorial], [t1]。 [MainProfilePreview], [t1].[SetSound], [t1].[EmailNotification], [t1].[UsernameOld], [t1].[UsernameChangeDate] FROM [UserPM] AS [t0] INNER JOIN [User] AS [ t1] ON [t1].[UserID] = [t0].[RecieverID] WHERE ([t0].[RecieverID] = @p0) AND (NOT ([t0].[IsDeletedRec] = 1)) ORDER BY [t0].[Timestamp] DESC

4

2 回答 2

0

我找到了一个解决方案:

起初似乎使用 DataLoadOptions 不太好,其次当您只需要 1 时加载具有 30 列的表并不聪明。

为了解决这个问题,我制作了一个涵盖所有必要领域的视图,当然还有连接。

它将时间从 5.0 秒减少到 230 毫秒!

于 2013-10-23T15:22:54.407 回答
0

如果您想摆脱 LoadWith,您可以明确选择您的字段:

public static List<Tuple<UserPM, User> > GetAllPMsAsReciepient(Guid userID)
{
    using (var dataContext = new RPGDataContext())
    {
        return (
            from a in dataContext.UserPMs 
            where a.RecieverID == userID 
            && !a.IsDeletedRec 
            orderby a.Timestamp descending 
            select Tuple.Create(a, a.User1)
        ).ToList();
    }
}
于 2013-10-23T13:53:38.583 回答