LINQ在列表或表格上更快吗?

时间:2011-03-03 14:44:53

标签: c# sql visual-studio linq

我有很多疑问要做,我想知道查询List和DataTable甚至SQL服务器索引表之间是否存在显着的性能差异?或者如果我选择其他类型的系列,它会更快吗?

总的来说,你怎么看?

谢谢!

2 个答案:

答案 0 :(得分:4)

在内存中查询任何几乎总是更快,例如List<T>DataTable对数据库。

话虽如此,你必须先将数据放入内存对象(如List)才能查询,所以我当然希望你不要考虑将数据库转储到List<T>中以便快速查询。这将是一个非常糟糕的想法。

我是否明白了你的问题?

答案 1 :(得分:2)

您可能会将Linq与数据库查询语言混淆。我建议你阅读Linq,尤其是IQueryable vs IEnumerable

简而言之,Linq是一种代码内查询语言,可以指向几乎任何数据集合,以与SQL类似的方式执行搜索,投影,聚合等,但不是仅限于RDBMSes。从表面上看,它不是像SQL这样的数据库查询语言;它只能通过使用IQueryable提供程序,Linq2SQL,Linq2Azure,Linq for Entities来翻译成一个......列表继续。

Linq的IEnumerable端,它对已经在堆中的内存中对象起作用,几乎肯定会比IQueryable端表现更好,IQueryable端存在要转换为SQL等本机查询语言。然而,这并不是因为语言任何一方存在固有的弱点或力量。相反,它是(通常)必须通过网络通道发送已翻译的IQueryable命令并获得相同结果的因素,这将比本地计算机的内存执行速度慢得多。

然而,从数据存储中提取记录并创建内存中对象表示的“繁重工作”必须在某个时间完成,而IQueryable Linq几乎肯定比将所有记录实例化为内存中对象更快然后使用IEnumerable Linq(Linq 2 Objects)进行过滤以获取实际数据。

举例说明:你有一张桌子MyTable;它包含一个相对适中的2亿行。使用像Linq2SQL这样的Linq提供程序,您的代码可能如下所示:

//GetContext<>() is a method that will return the IQueryable provider
//used to produce MyTable entitiy objects

//pull all records for the past 5 days
var results = from t in Repository.GetContext<MyTable>()
              where t.SomeDate >= DateTime.Today.AddDays(-5)
              && t.SomeDate <= DateTime.Now
              select t;

这将被Linq2SQL IQueryable提供程序消化为这样的SQL字符串:

SELECT [each of MyTable's fields] FROM MyTable WHERE SomeDate Between @p1 and @p2; @p1 = '2/26/2011', @p2 = '3/3/2011 9:30:00'

SQL引擎可以很容易地消化此查询,以便完全返回所需的信息(比如500行)。

如果没有Linq提供商,但想要使用Linq,您可以这样做:

//GetAllMyTable() is a method that will execute and return the results of
//"Select * from MyTable"

//pull all records for the past 5 days
var results = from t in Repository.GetAllMyTable()
              where t.SomeDate >= DateTime.Today.AddDays(-5)
              && t.SomeDate <= DateTime.Now
              select t;

从表面上看,差异很微妙。在幕后,魔鬼在那些细节中。第二个查询依赖于为数据库中的每个记录检索和实例化对象的方法。这意味着它必须拉出所有这些记录,并为它们在内存中创建一个空间。这将为您提供一个包含2亿条记录的列表,由于这些记录中的每条记录都是通过网络传输的,现在已经停留在您的页面文件中,因此不再那么谦虚。第一个查询可能会在构建时引入一些开销,然后将表达式树摘要为SQL,但它比将整个表转储到内存中的集合并迭代它更为可取。