实体框架性能很慢

时间:2021-01-30 12:01:04

标签: c# .net sql-server asp.net-mvc entity-framework

我正在尝试使用 EF Database.SqlQuery 从数据库中检索数据。下面的代码需要将近 15 秒的时间来执行以获取输出。

await _context.Database.SqlQuery<sp_dataexec>("exec sp_dataexec").ToListAsync() 

如果我尝试在 SQL Server 中执行 sp_dataexec 存储过程,只需 4 秒即可执行。这个存储过程 sp_dataexec 只包含 select 语句并且它有 85k 条记录。请告诉我是否有其他方法可以更快地检索数据。

1 个答案:

答案 0 :(得分:1)

EF 解析需要一些时间,但 11 秒 85,000 行似乎有点多。确保 DbContext 未被重用并且具有完整的 ChangeTracker。

为了进行比较,我搭建了 AdventureWorks2017 并加载了 Sales.SalesOrderHeader:

public partial class SalesOrderHeader
{
    public int SalesOrderId { get; set; }
    public byte RevisionNumber { get; set; }
    public DateTime OrderDate { get; set; }
    public DateTime DueDate { get; set; }
    public DateTime? ShipDate { get; set; }
    public byte Status { get; set; }
    public bool? OnlineOrderFlag { get; set; }
    public string SalesOrderNumber { get; set; }
    public string PurchaseOrderNumber { get; set; }
    public string AccountNumber { get; set; }
    public int CustomerId { get; set; }
    public int? SalesPersonId { get; set; }
    public int? TerritoryId { get; set; }
    public int BillToAddressId { get; set; }
    public int ShipToAddressId { get; set; }
    public int ShipMethodId { get; set; }
    public int? CreditCardId { get; set; }
    public string CreditCardApprovalCode { get; set; }
    public int? CurrencyRateId { get; set; }
    public decimal SubTotal { get; set; }
    public decimal TaxAmt { get; set; }
    public decimal Freight { get; set; }
    public decimal TotalDue { get; set; }
    public string Comment { get; set; }
    public Guid Rowguid { get; set; }
    public DateTime ModifiedDate { get; set; }
}

在预热之后,它始终以大约 100,000 行/秒的速度加载到 DbContext 包括查询执行时间。

for (int i = 0; i < 10; i++)
{
    using (var db = new Adventureworks2017Context())
    {
        var sw = new Stopwatch();
        sw.Start();
        var orders = db.SalesOrderHeaders.ToList();
            
        sw.Stop();
        Console.WriteLine($"Loaded {orders.Count()} rows in {sw.ElapsedMilliseconds}ms, for {orders.Count() / (sw.ElapsedMilliseconds / 1000.0):F2}rows/sec");
    }
}

输出

Loaded 31465 rows in 1206ms, for 26090.38rows/sec
Loaded 31465 rows in 273ms, for 115256.41rows/sec
Loaded 31465 rows in 281ms, for 111975.09rows/sec
Loaded 31465 rows in 244ms, for 128954.92rows/sec
Loaded 31465 rows in 228ms, for 138004.39rows/sec
Loaded 31465 rows in 260ms, for 121019.23rows/sec
Loaded 31465 rows in 251ms, for 125358.57rows/sec
Loaded 31465 rows in 224ms, for 140468.75rows/sec
Loaded 31465 rows in 261ms, for 120555.56rows/sec
Loaded 31465 rows in 223ms, for 141098.65rows/sec

向表中添加行并没有真正改变事情:

Loaded 100000 rows in 1669ms, for 59916.12rows/sec
Loaded 100000 rows in 849ms, for 117785.63rows/sec
Loaded 100000 rows in 850ms, for 117647.06rows/sec
Loaded 100000 rows in 875ms, for 114285.71rows/sec
Loaded 100000 rows in 885ms, for 112994.35rows/sec
Loaded 100000 rows in 831ms, for 120336.94rows/sec
Loaded 100000 rows in 871ms, for 114810.56rows/sec
Loaded 100000 rows in 879ms, for 113765.64rows/sec
Loaded 100000 rows in 875ms, for 114285.71rows/sec
Loaded 100000 rows in 865ms, for 115606.94rows/sec

Loaded 1000000 rows in 9311ms, for 107399.85rows/sec
Loaded 1000000 rows in 10040ms, for 99601.59rows/sec
Loaded 1000000 rows in 9161ms, for 109158.39rows/sec
Loaded 1000000 rows in 7678ms, for 130242.25rows/sec
Loaded 1000000 rows in 9074ms, for 110204.98rows/sec
Loaded 1000000 rows in 8670ms, for 115340.25rows/sec
Loaded 1000000 rows in 8873ms, for 112701.45rows/sec
Loaded 1000000 rows in 8094ms, for 123548.31rows/sec
Loaded 1000000 rows in 10353ms, for 96590.36rows/sec
Loaded 1000000 rows in 8727ms, for 114586.91rows/sec

在台式机上运行的 EF Core 5.02、SQL Server 2019 和 EF,英特尔酷睿 i9-09900K