gpt4 book ai didi

c# - 与原始 SQL 执行时间相比, Entity Framework 的性能开销是多少?

转载 作者:太空狗 更新时间:2023-10-29 21:39:24 25 4
gpt4 key购买 nike

在我的应用程序 (EF6 + SQL Server) 中,我正在动态创建 EF 查询以启用丰富的搜索功能。

这些查询是通过链接一堆 Where() 谓词创建的,并通过使用少量聚合将结果投影到已知的 CLR 类型中。在所有情况下,EF 都会生成一个返回少量结果(大约 10 个)的 SQL 查询。

使用 SQL Profiler,我可以看到这些生成的查询在由数据库执行时的执行时间只有几毫秒。但是,除非查询非常简单,否则总执行时间(从我的代码调用 ToList() 或 Count())在几百毫秒内!代码是在 Release模式下构建的,并且在没有附加调试器的情况下进行了测试。

任何人都可以给我任何提示,说明我的方法可能有什么问题吗?与原始 SQL 执行时间相比,EF 的开销是否可能在时间上是两个数量级?

编辑:

这些是我用来过滤结果集的一些代码示例:

if (p.PriceMin != null)
query = query.Where(a => a.Terms.Any(t => t.Price >= p.PriceMin.Value));

if (p.StartDate != null && p.EndDate != null)
query = query.Where(a => a.Terms.Any(t => t.Date >= p.StartDate.Value && t.Date <= p.EndDate.Value));

if (p.DurationMin != null)
query = query.Where(a => a.Itinerary.OfType<DayElement>().Count() > p.DurationMin.Value - 2);

if (p.Locations != null && p.Locations.Count > 0)
{
var locs = p.Locations.Select(l => new Nullable<int>(l)).ToList();
query = query.Where(a => a.Itinerary.OfType<MoveToElement>().Any(e => locs.Contains(e.LocationId)) ||
a.Itinerary.OfType<StartElement>().Any(e => locs.Contains(e.LocationId)) ||
a.Itinerary.OfType<EndElement>().Any(e => locs.Contains(e.LocationId)));
}

然后我这样排序结果:

if (p.OrderById)
query = query.OrderBy(a => a.Id);
else if (p.OrderByPrice)
query = query.OrderByDescending(a => a.Terms.Average(t => t.Price));

如果我尝试连续多次执行相同的查询(使用相同的 DbContext 调用多个 query.Count()),执行时间大致相同,所以我猜在这种情况下 EF 的查询生成非常高效.看来瓶颈是别的……

最佳答案

一般来说,是的,EF 比原始 SQL 慢,因为很难预测 EF 将如何构建查询,而且 EF 不了解您的数据库索引或其结构。

无法准确说明开销是多少,因为它会因查询而异。如果您想使用 EF 优化您的查询,您将不得不尝试各种方法来链接您的 where 谓词并对结果进行基准测试。即使是最细微的差别也会产生很大的不同。

我自己遇到了一个问题,使用 .Any().Contains() 之间存在巨大差异,您可以在这里看到:Check if list contains item from other list in EntityFramework

结果是一样的,但是第二个查询快了大约 100 倍。所以是的,对于某些查询,EF 可能比原始 SQL 慢两个数量级。其他时候它会慢几毫秒。

关于c# - 与原始 SQL 执行时间相比, Entity Framework 的性能开销是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22223877/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com