2011-03-10 70 views
5

C#的语句下面块的过程中,如果 itemToSkip比0LINQ跳过()问题

int itemToSkip = 100; 
int itemToTake = 1000; 

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

如何解决它更大的无法检索数据?问题是什么?

+0

没有'Skip'和/或'Take',它能正常工作吗? – Jon 2011-03-10 15:18:40

+0

无跳过,是的,它确实有 – 2011-03-10 15:20:45

+0

该表格包含14 GB数据。所以我无法让他们全部。我必须跳过并采取 – 2011-03-10 15:21:24

回答

8

不知道你有什么提供商提供db.MYTABLEs。除非我们知道db.MYTABLEs的行为,否则真的不可能回答你的问题。

在正常LINQ,跳过不只是跳到;它必须遍历数据量才能跳过。因此,对于您的14GB数据表,它将迭代第一个“跳过”数量的记录。如果此迭代速度较慢,则不会通过跳过来保存任何cpu /时间。

对于一些供应商,例如一个SQL源,跳过可能使用游标来实现,这可能会很慢。如果是SQL Server,可以使用可能更快的关键字进行优化。

如果是LINQ到SQL,其转换使用“NOT EXISTS”子句中查询到SQL,这将是非常慢,因为它要经过整个表如果NOT EXISTS子句不会触及索引。请参阅以下(link):

的LINQ to SQL使用与SQL子查询转换跳过 NOT EXISTS 条款。这种转换有 以下限制:

  • 参数必须是一个集合。即使订购,Multisets也不受支持。

  • 生成的查询可以比在其上施加跳过基本查询生成查询要复杂得多。这种复杂性会导致性能下降甚至超时。

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

仅关于使用随机存取功能,例如商在内存阵列,将跳过是非常快,因为供应商可以直接跳跃前进。

最坏的情况将是,如果你是在一个供应商,如果你使用跳过/接招自动排序整个数据集运行。如果你有14GB的数据,那么这种情况会非常缓慢。

你需要尝试一些,看看你的程序是挂在跳跃,或只是占用所有的CPU试图遍历。

如果您只是想将数据分割成可管理的块,你可能不应该使用跳过/带,其每次重新查询数据源。

3

跳过通常坚持在具有明确的排序顺序。尝试

var itemList = db.MYTABLEs.OrderBy(r => r.Id).Skip(itemToSkip) 

或类似。

+0

@Rup我不认为这是订购1100万行的情况下 – msarchet 2011-03-10 15:22:22

+0

是相当困难的:-( – 2011-03-10 15:23:02

+1

@Rup:到底为什么它需要一个排序? – Jon 2011-03-10 15:23:23

0

我认为,你的DBMS是不支持直接跳过,因此它可能会要求所有的数据,这取决于供应商。

+1

您是否认为Sql Server 2008&System.Data.SqlClient提供程序和.NET 3.5 Framework可能存在此问题? – 2011-03-10 15:26:12

+0

他在谈论LINQ提供者,而不是ADO.NET提供者。所以你在MS SQL数据库上使用.NET 3.5上的ADO.NET Entity Framework比? – Steven 2011-03-10 15:32:14

+0

@阿美特阿尔金:是的,我认为是。 MSSQL服务器有一个名为ROW_NUMBER()的方法,该方法以从1开始的返回行的编号。因此,如果您想要将行100000返回到100010,则需要先请求所有100010行。请参阅此处的示例:http://stackoverflow.com/questions/187998/row-offset-in-ms-sql-server – 2011-03-10 15:32:34

0

带有这样大的表是可能的,只是需要很长时间才能返回,并且由于缺少索引需要很长时间,您需要进行一些分析以查看基础查询,您无法诊断问题只是看在LINQ代码