简介
我一直在研究它们之间的区别。我决定亲自动手测试它们,因为我想看看它们之间的性能差异(如果有的话),并理解其中的原因。
我创建了一个简单的控制台应用程序。我使用Entity Framework和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会更快,因为它有可能优化查询,使得过滤器(例如memo是Active
)由SQL执行,并且当调用ToList()
时返回的结果非常少。
然而,我的发现却证明了相反的结论。为什么?我确信在我的测试中,IQueryable 应该更快。我特意设置了这个来证明。
“这是因为你使用了 IQueryable(Of Memo)!”
我也这样想。我听说将我的对象强制转换为IQueryable可能不好,因为它仍然需要从IEnumerable进行转换。所以我尝试了这个:
Dim iQuer As IEnumerable(Of Memo) = _db.Memos.AsQueryable
这确实提高了性能,所以测试 3只需要17ms就完成了,而不是186ms。但它仍然比测试 2的6ms要慢。
这是怎么回事呢?