C# 仅针对每个唯一ID的前N行进行高效查询
这是问题的后续行动 TLDR: 问题是: 我想过滤一个查询,只保留每个唯一ID的前n行 答案是:C# 仅针对每个唯一ID的前N行进行高效查询,c#,sql,linq,linq-to-sql,C#,Sql,Linq,Linq To Sql,这是问题的后续行动 TLDR: 问题是: 我想过滤一个查询,只保留每个唯一ID的前n行 答案是: query = query.GroupBy(q => q.ID).SelectMany(g => g.Take(n)); 这个答案的问题是,对于80000多行,计算查询所需的时间比通过迭代进行过滤要长得多(foreach)(至少慢一倍)。查看此答案生成的SQL,使用了一个交叉应用,最有可能用于SelectMany() 描述交叉应用的作用: 应用运算符允许您联接两个表表达式;右表表达式每
query = query.GroupBy(q => q.ID).SelectMany(g => g.Take(n));
这个答案的问题是,对于80000多行,计算查询所需的时间比通过迭代进行过滤要长得多(foreach
)(至少慢一倍)。查看此答案生成的SQL,使用了一个交叉应用
,最有可能用于SelectMany()
描述交叉应用
的作用:
应用运算符允许您联接两个表表达式;右表表达式每次都会处理来自左表表达式的每一行
简而言之,我正在寻找一个过滤查询,它可以有效地收集每个唯一ID
的顶部N
行
使用解释SQL的Linq解决方案是理想的。L2S没有行号,因此不能使用Martin的技巧。我也经历过这个问题,据我所知,这是最佳的L2S解决方案(不以任何方式使用本机SQL) 您可以尝试将所有结果下拉到应用程序中,并在那里执行行号操作。这可能会损害或有利于性能。这取决于具体情况。我在SQL(底部的SQL 2000解决方案)中找到了答案,并设法实现了一个可查询的/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);
一个相当标准的“子查询”模式。在一个大的表上进行查询要快得多。另一种最常用的方法是对每个组进行最大n次查询的
ROW\u NUMBER()OVER(按ID顺序按Y划分)
,然后在此基础上进行筛选。不确定linq to sql是否可以生成该sql。当然,这种过滤方式比不使用过滤需要更多的计算
,因此效率的降低是可以理解的。编辑我的问题。很抱歉给你带来了困惑。