c# - LINQ Skip() 问题

标签 c# sql linq

下面的 C# 语句会阻塞进程并且无法检索数据,如果 itemToSkip 大于 0。

 int itemToSkip = 100;
 int itemToTake = 1000;

 var itemList = db.MYTABLEs.Skip(itemToSkip).Take(itemToTake).ToList();

我该如何解决?有什么问题吗?

最佳答案

不确定您有哪个供应商提供 db.MYTABLEs。除非我们知道 db.MYTABLEs 的行为方式,否则真的不可能回答您的问题。

在正常的 LINQ 中,skip 不只是向前跳过;它必须遍历数据量才能跳过。因此,对于您的 14gb 数据表,它将遍历第一个“跳过”的记录数。如果此迭代很慢,则您不会通过跳过来节省任何 CPU/时间。

对于某些提供商,例如对于 SQL 源,skip 可以使用游标来实现,这又会很慢。如果是SQL Server,可能会用关键字优化,可能会更快。

如果它是 LINQ-to-SQL,它会使用“NOT EXISTS”子句将查询转换为 SQL,这将非常慢,因为它必须经过整个 table 如果 NOT EXISTS 子句没有命中索引。请参阅以下内容 ( link ):

LINQ to SQL translates Skip by using a subquery with the SQL NOT EXISTS clause. This translation has the following limitations:

  • The argument must be a set. Multisets are not supported, even if ordered.

  • The generated query can be much more complex than the query generated for the base query on which Skip is applied. This complexity can cause decrease in performance or even a time-out.

换句话说,文档说“不要这样做”。

仅适用于具有随机访问功能的提供商,例如一个内存数组,将非常快地跳过,因为提供者可以直接跳到前面。

最坏的情况是,如果您在使用 Skip/Take 时自动对整个数据集进行排序的提供程序上运行。如果您有 14gb 的数据,那么这种排序会非常慢。

您需要进行更多试验,看看您的程序是否在跳过时挂起,或者只是占用所有 CPU 以尝试迭代。

如果您只是想将数据分成可管理的 block ,您可能不应该使用 skip/take,它每次都会重新查询数据源。

关于c# - LINQ Skip() 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5261717/

相关文章:

c# - 通过 jQuery 调用 asmx 服务时,如何传递参数?

mysql - SQL 一对多关系 - 如何根据多个对多属性来选择行?

mysql - 在 phpMyAdmin 中将 mysql 导出为 ASCII

c# - 动态 Linq to 实体排序与分页

c# - C# 项目列表中的唯一值

c# - Linq 从 List<string> 中包含

c# - 从 ASP.NET Web api 调用后端 .NET dll

c# - 在基类中检索子类类型?

c# - 调试在启动时崩溃的 C# 可执行文件

mysql - 如何使用子查询进行进一步的计算?