5

我有一个非常简单的 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

英孚 5.0.0 最低 1502 最高 2016 平均 1665.4

1M 行的所有时间(以毫秒为单位)。

.Net 4.5

更新 2:

放弃 105 中的前五个测试

英孚 6.0.1最小 2698 最大 4383 平均 3136

EF 5.0.0最小 1426 最大 2922 平均 1628

更新 3:

根据此处的建议重新创建 TT 模板后

EF 6.0.1最小 2589 最大 4279 平均 3027

使用此处描述的 NGEN 编译 EF6 后

EF 6.0.1最小 2644 最大 4322 平均 3045.7

更新 4:

更改为 AsEnumerable 后

英孚 6.0.1最小 2661 最大 4658 平均 3134.6

4

1 回答 1

3

在 EF6 中,我们将默认数据检索行为从流式更改为缓冲(请参阅此处了解原因)。缓冲会增加额外的开销,这在执行无跟踪查询时尤其明显,例如投影到未映射的 CLR 类型或通过 AsNoTracking 扩展方法。为了缓解这个问题,我们添加了AsStreaming扩展方法,该方法在每个查询的基础上关闭缓冲。使用 AsStreaming 应该可以为您提供类似 EF5 的性能。

于 2013-11-08T00:00:19.323 回答