简体   繁体   English

使用Linq选择前100条记录

[英]Selecting first 100 records using Linq

How can I return first 100 records using Linq? 如何使用Linq返回前100条记录?

I have a table with 40million records. 我有一张有4000万条记录的桌子。

This code works, but it's slow, because will return all values before filter: 此代码有效,但速度很慢,因为将在过滤之前返回所有值:

var values = (from e in dataContext.table_sample
              where e.x == 1
              select e)
             .Take(100);

Is there a way to return filtered? 有没有办法返回过滤? Like T-SQL TOP clause? 喜欢T-SQL TOP子句?

No, that doesn't return all the values before filtering. 不,在过滤之前不会返回所有值。 The Take(100) will end up being part of the SQL sent up - quite possibly using TOP. Take(100)将最终成为SQL发送的一部分 - 很可能使用TOP。

Of course, it makes more sense to do that when you've specified an orderby clause. 当然,当你指定了orderby子句时,更有意义。

LINQ doesn't execute the query when it reaches the end of your query expression. LINQ在到达查询表达式的末尾时不执行查询。 It only sends up any SQL when either you call an aggregation operator (eg Count or Any ) or you start iterating through the results. 只有在调用聚合运算符(例如CountAny )或者开始迭代结果时,它才会发送任何SQL。 Even calling Take doesn't actually execute the query - you might want to put more filtering on it afterwards, for instance, which could end up being part of the query. 甚至调用Take实际上并不执行查询 - 例如,您可能希望在其之后对其进行更多过滤,这可能最终成为查询的一部分。

When you start iterating over the results (typically with foreach ) - that's when the SQL will actually be sent to the database. 当你开始遍历结果(通常foreach ) - 这是当SQL实际上将被发送到数据库。

(I think your where clause is a bit broken, by the way. If you've got problems with your real code it would help to see code as close to reality as possible.) (顺便说一下where我认为你的where子句有点破碎。如果你的实际代码出现问题,那么看到代码尽可能接近现实会有所帮助。)

我认为你在进入前100名之前返回所有记录并不正确。我认为Linq决定在执行查询时(即Lazy Loading)SQL字符串将是什么,并且您的数据库服务器将优化出来。

Have you compared standard SQL query with your linq query? 您是否将标准SQL查询与linq查询进行了比较? Which one is faster and how significant is the difference? 哪一个更快,差异有多大?

I do agree with above comments that your linq query is generally correct, but... 我同意上述评论,你的linq查询通常是正确的,但......

  • in your 'where' clause should probably be x==1 not x=1 (comparison instead of assignment) 在你的'where'子句中应该是x == 1而不是x = 1(比较而不是赋值)
  • 'select e' will return all columns where you probably need only some of them - be more precise with select clause (type only required columns); 'select e'将返回所有可能只需要其中一些列的列 - 使用select子句更精确(仅键入所需的列); 'select *' is a vaste of resources 'select *'是一种资源
  • make sure your database is well indexed and try to make use of indexed data 确保您的数据库编入索引并尝试使用索引数据

Anyway, 40milions records database is quite huge - do you need all that data all the time? 无论如何,40milions记录数据库非常庞大 - 你是否一直需要所有这些数据? Maybe some kind of partitioning can reduce it to the most commonly used records. 也许某种分区可以将它减少到最常用的记录。

I agree with Jon Skeet, but just wanted to add: 我同意Jon Skeet,但只是想补充一下:

  1. The generated SQL will use TOP to implement Take(). 生成的SQL 使用TOP来实现Take()。

  2. If you're able to run SQL-Profiler and step through your code in debug mode, you will be able to see exactly what SQL is generated and when it gets executed. 如果您能够在调试模式下运行SQL-Profiler并逐步执行代码,那么您将能够确切地看到生成的SQL以及何时执行它。 If you find the time to do this, you will learn a lot about what happens underneath. 如果您有时间这样做,您将了解到底下发生的事情。

  3. There is also a DataContext.Log property that you can assign a TextWriter to view the SQL generated, for example: 还有一个DataContext.Log属性,您可以指定TextWriter来查看生成的SQL,例如:

    dbContext.Log = Console.Out; dbContext.Log = Console.Out;

  4. Another option is to experiment with LINQPad . 另一个选择是试验LINQPad LINQPad allows you to connect to your datasource and easily try different LINQ expressions. LINQPad允许您连接到您的数据源并轻松尝试不同的LINQ表达式。 In the results panel, you can switch to see the SQL generated the LINQ expression. 在结果面板中,您可以切换到查看SQL生成的LINQ表达式。

I'm going to go out on a limb and guess that you don't have an index on the column used in your where clause. 我打算走出困境,猜测你的where子句中使用的列没有索引。 If that's the case then it's undoubtedly doing a table scan when the query is materialized and that's why it's taking so long. 如果是这种情况,那么当查询实现时,毫无疑问会进行表扫描,这就是为什么它需要这么长时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM