我一直在研究两者之间的区别。我决定亲自动手测试它们,因为我希望看到两者之间的性能差异(如果有的话)并理解为什么。
我创建了一个简单的控制台应用。我正在使用Entity Framework和SQL Server。我创建了一个指向数据库表的模型。该表有大约1000条记录。
Dim _db As New SampleEntities
Dim sw As New Stopwatch
Dim allMemos As IEnumerable(Of Memo) = _db.Memos
sw.Start()
allMemos.ToList()
sw.Stop()
Dim iEnum As IEnumerable(Of Memo) = _db.Memos.AsEnumerable
sw.Restart()
iEnum.Where(Function(f) f.Active).ToList()
sw.Stop()
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 会更快。我故意将它设置为显示它。
我也这么认为。我听说过将我的对象转换为IQueryable可能会很糟糕,因为无论如何它必须从IEnumerable转换。所以我尝试了这个:
Dim iQuer As IEnumerable(Of Memo) = _db.Memos.AsQueryable
确实提高了性能,因此测试3 需要17ms而不是186ms。但它仍然比6毫秒慢(测试2)。
这里发生了什么?
答案 0 :(得分:2)
我不知道_db.Memos在测试2中返回了什么
Dim iEnum As IEnumerable(Of Memo) = _db.Memos.AsEnumerable
所有记录都可以在那里加载到内存中。
在测试3中,当您致电ToList
时加载记录:
iQuer.Where(Function(f) f.Active).ToList()
你应该做两件事: