为什么IEnumerable比IQueryable更快?

时间:2013-06-19 01:54:32

标签: .net performance entity-framework ienumerable iqueryable

简介

我一直在研究两者之间的区别。我决定亲自动手测试它们,因为我希望看到两者之间的性能差异(如果有的话)并理解为什么

我创建了一个简单的控制台应用。我正在使用Entity Framework和SQL Server。我创建了一个指向数据库表的模型。该表有大约1000条记录。

测试

Dim _db As New SampleEntities
Dim sw As New Stopwatch

测试1 - 966ms

Dim allMemos As IEnumerable(Of Memo) = _db.Memos
sw.Start()
allMemos.ToList()
sw.Stop()

测试2-6ms

Dim iEnum As IEnumerable(Of Memo) = _db.Memos.AsEnumerable
sw.Restart()
iEnum.Where(Function(f) f.Active).ToList()
sw.Stop()

测试3 - 186ms

Dim iQuer As IQueryable(Of Memo) = _db.Memos.AsQueryable
sw.Restart()
iQuer.Where(Function(f) f.Active).ToList()
sw.Stop()

我的发现

在我开始之前,我的研究告诉我,在许多情况下,IQueryable更快,因为它可能会优化查询,以便过滤器(即备忘录为Active)由SQL执行,因此很少有结果在调用ToList()时返回。

然而,我的研究结果表明相反。为什么?我确信在我的测试中,IQueryable 更快。我故意将它设置为显示它。

“这是因为您使用iQuer As IQueryable(备忘录)!”

我也这么认为。我听说过将我的对象转换为IQueryable可能会很糟糕,因为无论如何它必须从IEnumerable转换。所以我尝试了这个:

Dim iQuer As IEnumerable(Of Memo) = _db.Memos.AsQueryable

确实提高了性能,因此测试3 需要17ms而不是186ms。但它仍然比6毫秒慢(测试2)。

这里发生了什么?

1 个答案:

答案 0 :(得分:2)

我不知道_db.Memos在测试2中返回了什么

Dim iEnum As IEnumerable(Of Memo) = _db.Memos.AsEnumerable

所有记录都可以在那里加载到内存中。

在测试3中,当您致电ToList时加载记录:

  iQuer.Where(Function(f) f.Active).ToList()

你应该做两件事:

  1. 在分配前移动秒表线,然后比较结果。
  2. 在数据库中设置跟踪,以查看代码实际访问数据库的位置。