我可以做些什么来提高这个查询的速度?

What can I do to improve the speed of this query?

我有一个 linq 查询 returns 用户查看的最后一页基于 table 的页面点击率。这些字段只是 TimeStampUserIDURL,它们是从用户 activity 记录的。查询如下所示:

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 向我们保证 table 在所有正确的位置都有索引,问题一定出在查询上。

这有什么本质上的错误或不好吗,或者是否有更有效的方法来获得相同的结果?

你可以试试:

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,将返回两个 "rows",与此仅返回一个。

所以您尝试使用 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 将组合扁平化为记录。我认为这比您的查询更有效。