3

介绍

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

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

测试

Dim _db As New SampleEntities
Dim sw As New Stopwatch

测试 1 - 966 毫秒

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 - 186 毫秒

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

我的发现

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

然而,我的研究结果却恰恰相反。为什么?我确信在我的测试中 IQueryable更快。我故意设置它来显示这一点。

“那是因为你使用了 iQuer As IQueryable(Of Memo)!”

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

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

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

这里发生了什么?

4

1 回答 1

2

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

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

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

在测试 3 中,当您调用时会加载记录ToList

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

你应该做两件事:

  1. 在作业前移动秒表线,然后比较结果。
  2. 在您的数据库中设置跟踪以查看代码实际命中数据库的位置。
于 2013-06-21T09:21:01.323 回答