我该怎么做才能提高此查询的速度?

时间:2015-03-13 12:41:08

标签: c# linq-to-sql

我有一个linq查询,它根据页面命中表返回用户查看的最后一页。这些字段只是TimeStampUserIDURL,它们是从用户活动中记录的。查询如下所示:

public static IQueryable GetUserStatus()
{
    var ctx = new AppEntities();
    var currentPageHits = ctx.Pagehits
        .GroupBy(x => x.UserID)
        .Select(x => x.Where(y => y.TimeStamp == x.Max(z => z.TimeStamp)))
        .SelectMany(x => x);

    return currentPageHits.OrderByDescending(o => o.TimeStamp);
}

查询工作正常,但运行缓慢。我们的DBA向我们保证,该表在所有正确的位置都有索引,并且问题必须在查询中。

是否存在任何内在错误或有不良之处,或者是否有更有效的方法来获得相同的结果?

2 个答案:

答案 0 :(得分:3)

你可以尝试:

var currentPageHits2 = ctx.Pagehits
    .GroupBy(x => x.UserID)
    .Select(x => x.OrderByDescending(y => y.TimeStamp).First())
    .OrderByDescending(x => x.TimeStamp);

但速度应该是一样的。

请注意,此查询与您的查询之间存在细微差别...如果 UserId 有两个" max TimeStamp " PageHits 使用相同的 TimeStamp ,两行"行"将被退回,只有一个将被退回。

答案 1 :(得分:2)

所以你试着用LINQ实现DENSE_RANK() OVER (PARTITION BY UserID ORDER BY TimeStamp DESC)?因此,根据Timestamp,每个用户组的所有最新记录。你可以尝试:

public static IQueryable GetUserStatus()
{
    var ctx = new AppEntities();
    var currentPageHits = ctx.Pagehits
        .GroupBy(x => x.UserID)
        .SelectMany(x => x.GroupBy(y => y.TimeStamp).OrderByDescending(g=> g.Key).FirstOrDefault())
        .OrderByDescending(x => x.TimeStamp);

    return currentPageHits;
}

因此,它按用TimeStamp对用户组进行分组,然后它采用最新的组(如果是关系,则为一个或多个记录)。 SelectMany将goups压平为记录。我认为这比你的查询更有效。