LINQ 中的 count VS select - 哪个更快?
我在整个应用程序中使用 IQueryable
接口,并推迟在数据库上执行 SQL,直到像 .ToList()
这样的方法,
我需要找到某些对象的计数列出有时不需要使用正在计数的列表中的数据。 根据我的 SQL 经验,我知道 SQL COUNT() 对数据库的工作量远少于返回所有行的等效 SELECT 语句。
所以我的问题是:从 IQueryable
的 Count()
方法返回计数比渲染 IQueryable< 在数据库上的工作会更少吗;T>
到列表并调用列表的 Count()
方法?
我怀疑它会考虑到 ToList()
将触发 SELECT sql,然后在单独的查询中计算行数。 我希望 IQueryable
上的 Count()
只是为 sql COUNT() 查询呈现 sql。 但我不确定。 你知道吗?
I'm using IQueryable<T>
interfaces throughout my application and defer execution of SQL on the DB until methods like .ToList()
I will need to find the Count of certain lists sometimes -without- needing to use the data in the list being counted. I know from my SQL experience that a SQL COUNT() is far less work for the DB than the equivalent SELECT statement that returns all the rows.
So my question is: will it be less work on the DB to return the count from the IQueryable<T>
's Count()
method than rendering the IQueryable<T>
to a list and invoking the list's Count()
method?
I suspect it will given that the ToList()
will fire the SELECT sql and then in a separate query count the rows. I'm hoping the Count()
on the IQueryable<T>
simply renders out the sql for a sql COUNT() query instead. But im not certain. Do you know?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我不确定这是否是一个硬性规定,但是添加到 Iqueryable 的 linq 方法将被添加到 linq 表达式树中 - 除非它们是实际导致树被评估的方法之一(例如 ToList 和 Single ETC)。
对于 LinqToSql,您将知道它是否无法将某些内容转换为 SQL 语句,因为您将收到一个运行时异常,表明该方法不受支持。
例如,
在上面,Select() 和 Distinct() 包含在传递给服务器的 sql 查询中,因为它们被添加到 Iqueryable 中。 Count() 只是作用于 sql 查询返回的列表。 所以你不想这样做:-)
在你的情况下,Count()肯定会比Select()更快,因为生成的sql语句确实会合并计数,所以服务器只需要返回一个数字而不是比行列表。
I'm not sure if it's a hard and fast rule, but linq method you add to an Iqueryable will be added into the linq expression tree - unless they are one of the methods that actually cause the tree to be evaluated (like ToList and Single etc).
In the case of LinqToSql you'll know if it can't convert something into the SQL statement because you'll get a runtime exception stating that the method is not supported.
eg
In the above, Select() and Distinct() are included in the sql query passed to the server because they are added to an Iqueryable. Count() is just acting on the list that was returned by the sql query. So you don't want to do it that way :-)
In your case, Count() will definitely be faster that Select() because the resulting sql statement will indeed incorporate the count so the server only needs to return a single number rather than a list of rows.
如果您使用的是 SQL Server,Count() 仍然非常昂贵,因为它会导致表扫描(或索引扫描,请参阅主要答案的评论)。 而且,默认情况下,Linq 不使用读未提交隔离级别,这会因锁定而使情况变得更糟。
如果您可以接受脏结果和总行数的近似值,则以下代码将比使用 Count() 快得多。 根据我的经验,此代码返回的值很少与真实的行数不同。
If you're using SQL Server, Count() is still very expensive because it causes a table scan (or index scan, see comments on primary answer). And, by default Linq doesn't use the read uncomitted isolation level, which makes things worse due to locking.
If you can live with the result being a dirty result and an approximation of the total number of rows, the following code will be considerably faster than using Count(). In my experience, the value returned by this code is rarely different than the true count of rows.
调用
ToList()
将返回一个包含所有数据的真正的List
,这意味着获取所有数据。 不好。调用
Count()
确实应该呈现 SQL 以在数据库端进行计数。 好多了。然而,检查这一点的最简单方法是在您的数据上下文中启用日志记录(或针对您的特定提供商的任何等效项)并查看实际发送的查询。
Calling
ToList()
will return a genuineList<T>
with all the data, which means fetching all the data. Not good.Calling
Count()
should indeed render the SQL to do the count on the database side. Much better.The simplest way to check this, however, is to enable logging in your data context (or whatever the equivalent is for your particular provider) and see what queries are actually being sent.