1

这是对这个问题的跟进。

TLDR:

问题:

我想过滤查询以仅保留每个唯一 ID 的前 n 行。

答案:

query = query.GroupBy(q => q.ID).SelectMany(g => g.Take(n));

这个答案的问题在于,对于超过 80,000 行,评估查询所花费的时间比通过迭代 ( foreach) 过滤要长得多(至少慢两倍)。查看此答案生成的 SQL,CROSS APPLY使用了 a,最有可能用于SelectMany().

这个链接描述了什么CROSS APPLY

APPLY 运算符允许您连接两个表表达式;每次从左表表达式的每一行处理右表表达式。

简而言之,我正在寻找一个过滤查询,它可以有效地收集N每个唯一的顶行ID

具有解释性 SQL 的 Linq 解决方案将是理想的。

4

2 回答 2

2

我在 SQL 中找到了答案底部的 SQL 2000 解决方案)并设法实现了 Queryable/Linq 版本:

query = tableQueryable.Where(a =>
          tableQueryable.Where(b => b.ID == a.ID)
            .OrderByDescending(o => o.Timestamp)
            .Take(N)
            .Select(s => s.PK)
          .Contains(a.PK)
        ).OrderByDescending(d => d.Timestamp);

一个相当标准的“子查询”模式。在大桌子上要快得多。

于 2013-09-17T19:30:16.130 回答
1

L2S 没有行号,因此无法使用 Martin 的技巧。我也遇到过这个问题,据我所知,这是最佳的 L2S 解决方案(不以任何方式使用本机 SQL)。

您可以尝试将所有结果拉入应用程序并在那里执行行号操作。这可能会损害或有利于性能。是哪一种取决于具体情况。

于 2013-09-11T15:10:08.873 回答