如何使用Linq返回前100条记录?
我有一张有4000万条记录的桌子。
此代码有效,但速度很慢,因为它会在filter之前返回所有值:
var values = (from e in dataContext.table_sample
where e.x == 1
select e)
.Take(100);
有没有办法返回过滤?喜欢T-SQL TOP子句吗?
答案 0 :(得分:28)
不,在过滤之前不会返回所有值。 Take(100)
最终将成为发送的SQL的一部分 - 很可能使用TOP。
当然,当您指定orderby
子句时,这样做会更有意义。
LINQ在到达查询表达式的末尾时不执行查询。只有当您调用聚合运算符(例如Count
或Any
)或者您开始迭代结果时,它才会发送任何SQL。甚至调用Take
实际上并不执行查询 - 例如,您可能希望在此之后对其进行更多过滤,这可能最终成为查询的一部分。
当您开始迭代结果时(通常使用foreach
) - 当SQL实际发送到数据库时。
(顺便说一下,我认为你的where
条款有点不完整。如果你的真实代码出现问题,那么将代码视为接近现实可能的。)
答案 1 :(得分:2)
我认为你在进入前100名之前返回所有记录并不正确。我认为Linq决定执行查询时的SQL字符串(也称为Lazy Loading)和数据库服务器将优化它。
答案 2 :(得分:2)
您是否将标准SQL查询与linq查询进行了比较?哪一个更快,差异有多大?
我同意上述评论,你的linq查询通常是正确的,但是......
无论如何,40milions记录数据库非常庞大 - 你是否一直需要所有数据?也许某种分区可以将它减少到最常用的记录。
答案 3 :(得分:2)
我同意Jon Skeet,但只是想补充一下:
生成的SQL 将使用TOP来实现Take()。
如果您能够运行SQL-Profiler并在调试模式下逐步执行代码,您将能够确切地看到生成什么SQL以及何时执行它。如果你有时间做这件事,你将会了解到底下发生的事情。
还有一个DataContext.Log属性,您可以指定TextWriter来查看生成的SQL,例如:
dbContext.Log = Console.Out;
另一种选择是试验LINQPad。 LINQPad允许您连接到您的数据源并轻松尝试不同的LINQ表达式。在结果面板中,您可以切换以查看生成LINQ表达式的SQL。
答案 4 :(得分:1)
我要走出困境,并猜测你的where子句中使用的列没有索引。如果是这种情况,那么当查询实现时,毫无疑问会进行表扫描,这就是它花费这么长时间的原因。