我有一个非常简单的 edmx 模型,一个数据库和一个实体用于一个数据库表。从本地虚拟数据库服务器测试所有记录的顺序检索。
using System;
using System.Linq;
namespace ConsoleApplication1
{
using System.Diagnostics;
private static readonly ConcurrentBag<long> Stats = new ConcurrentBag<long>();
static void Main(string[] args)
{
for (int i = 0; i < 5; i++)
{
var sw = Stopwatch.StartNew();
using (var ctx = new ScratchEntities())
{
foreach (var invoice in ctx.Invoices.Select(
s => new
{
s.Id,
s.Amount,
s.DueDate
}))
{
}
}
sw.Stop();
Stats.Add(sw.ElapsedMilliseconds);
}
Console.WriteLine("Min {0} Max {1} Avg {2}", Stats.Min(), Stats.Max(), Stats.Average());
}
}
在 EF 4 和 5 下,执行时间大约为 2-2.5 秒。升级到Nuget的EF6,快10s了。
同样,当我在 ctx.Invoices 上使用 foreach 时,与在 ctx.Invoices.Select(s=>new{all columns here}) 上使用 foreach 相比,它也需要 4-5 倍的时间。
困惑。
更新:
迭代 5 次
EF 6.0.1 最低 3082 最高 9231 平均 4462.8
EF 5.0.0 最低 1502 最高 2016 平均 1665.4
1M 行的所有时间以毫秒为单位。
.Net 4.5
更新 2:
丢弃 105 个测试中的前五个测试
EF 6.0.1 最低 2698 最高 4383 平均 3136
EF 5.0.0 最低 1426 最高 2922 平均 1628
更新 3:
根据建议重新创建 TT 模板后 here
EF 6.0.1 最低 2589 最高 4279 平均 3027
使用 NGEN 编译 EF6 后 here
EF 6.0.1 最小 2644 最大 4322 平均 3045.7
更新 4:
改为 AsEnumerable 后
EF 6.0.1 最低 2661 最高 4658 平均 3134.6
最佳答案
在 EF6 中,我们将默认数据检索行为从流式更改为缓冲(请参阅 here 了解原因)。缓冲会增加额外的开销,这在执行非跟踪查询(例如投影到未映射的 CLR 类型或通过 AsNoTracking 扩展方法)时尤其明显。为了缓解这个问题,我们添加了 AsStreaming 在每个查询的基础上关闭缓冲的扩展方法。使用 AsStreaming 应该可以提供类似 EF5 的性能。
关于sql - Entity Framework 性能下降,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19670100/