介绍
我一直在研究两者的区别。我决定亲自动手并测试它们,因为我想看看两者之间的性能差异(如果有的话)并了解原因。
我创建了一个简单的控制台应用程序。我正在使用实体框架和 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)。
这里发生了什么?