高实体框架核心执行时间

时间:2019-09-04 10:21:14

标签: asp.net-core entity-framework-core

我已经构建了一个简单的Asp.Net Core MVC应用程序,可用于在工作中从MSSQL数据库中的视图显示数据。从SSMS查询此视图时,平均执行时间约为100毫秒。在我的应用中执行相同的查询时,执行时间约为800毫秒至1.5秒。

这是控制器中的LINQ:

public IActionResult Index()
{
    var query =
    from p in _context.vWebQuery
    where p.Almachine == "600L"
    orderby p.Aldatsta
    select p;
    return View(query);
}

这是实体类:

namespace BetaKestrel2.Models
{
    public class vWebQuery
    {
        public double Wruntim { get; set; }
        public short Wper { get; set; }
        public double Quantity { get; set; }
        [Column("Total Op TIme")]
        public double? TotalTime { get; set; }
        public string Alwon { get; set; }
        public short Alopnum { get; set; }
        public string Almachine { get; set; }
        public double Alpersta { get; set; }
        [DisplayFormat(DataFormatString = "{0:F2}")]
        public double Allen { get; set; }
        public short Alprevop { get; set; }
        [DisplayFormat(DataFormatString = "{0:d}")]     
        public DateTime Aldatsta { get; set; }
        public string Altimsta { get; set; }
        public string Alstatus { get; set; }
        public short Alperno { get; set; }
        public string Macid { get; set; }
        public string Macdesc { get; set; }
        public string Partid { get; set; }
        public string Partrevisionid { get; set; }
        public string Routingmethod { get; set; }
        public double Wqleft { get; set; }
        public string Wstate { get; set; }
        public string Wdesc { get; set; }
        public string Partdesc { get; set; }
        public string Toolid { get; set; }
        public string Childpartid { get; set; }
        public string msection { get; set; }

    }
}

和DbContext :(将.Net Core 3.0用于.HasNoKey())

public partial class EfacDBContext : DbContext
{
    public EfacDBContext()
    {
    }

    public EfacDBContext(DbContextOptions<EfacDBContext> options)
        : base(options)
    {
    }

    public DbSet<vWebQuery>         vWebQuery { get; set; }
    public DbSet<vGRN>              vGRN      { get; set; }
    public DbSet<vQuotationTracker> vQuotationTracker { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {

        modelBuilder.Entity<vWebQuery>(entity =>
        {
            entity.HasNoKey();
            entity.ToTable("vwebquery");
        });

还有一个示例.cshtml视图:

@model IEnumerable<BetaKestrel2.Models.vWebQuery>

@{
    ViewData["Title"] = "600L";
    string highlight = "";
}


<h1>Work Centre Plan - @ViewData["Title"]</h1>

<table class="table table-sm table-bordered">
    <thead>
        <tr>
            <th>Works Order</th>
            <th>Part Number</th>
            <th>Description</th>
            <th>Op Number</th>
            <th>Quantity</th>
            <th>Latest Start Date</th>
            <th>Previous Op</th>
            <th>Total Op Time (mins)</th>
            <th>Status</th>
            <th>Qty Left</th>
        </tr>
    </thead>
    <tbody>

    @foreach (var item in Model)
    {

        @if (item.Wstate == "COMP")
        {
            highlight = "background-color: green;";
        }
        else if (item.Alprevop == 0)
        {
            highlight = "background-color: yellow;";
        }
        else
        {
            highlight = "";
        }
        <tr style="@highlight">
            <td>@Html.DisplayFor(modelItem => item.Alwon)</td>
            <td>@Html.DisplayFor(modelItem => item.Partid)</td>
            <td>@Html.DisplayFor(modelItem => item.Partdesc)</td>
            <td>@Html.DisplayFor(modelItem => item.Alopnum)</td>
            <td>@Html.DisplayFor(modelItem => item.Quantity)</td>
            <td>@Html.DisplayFor(modelItem => item.Aldatsta)</td>
            <td>@Html.DisplayFor(modelItem => item.Alprevop)</td>
            <td>@Html.DisplayFor(modelItem => item.TotalTime)</td>
            <td>@Html.DisplayFor(modelItem => item.Wstate)</td>
            <td>@Html.DisplayFor(modelItem => item.Wqleft)</td>
        </tr>
    }
    </tbody>
</table>

EF Core转换为以下SQL

SELECT 
    [v].[Aldatsta]
    ,[v].[Allen]
    ,[v].[Almachine]
    ,[v].[Alopnum]
    ,[v].[Alperno]
    ,[v].[Alpersta]
    ,[v].[Alprevop]
    ,[v].[Alstatus]
    ,[v].[Altimsta]
    ,[v].[Alwon]
    ,[v].[Childpartid]
    ,[v].[Macdesc]
    ,[v].[Macid]
    ,[v].[Partdesc]
    ,[v].[Partid]
    ,[v].[Partrevisionid]
    ,[v].[Quantity]
    ,[v].[Routingmethod]
    ,[v].[Toolid]
    ,[v].[Total Op TIme]
    ,[v].[Wdesc]
    ,[v].[Wper]
    ,[v].[Wqleft]
    ,[v].[Wruntim]
    ,[v].[Wstate]
    ,[v].[msection]
FROM [vwebquery] AS [v]
WHERE 
    [v].[Almachine] = N'BENDD'
AND [v].[Almachine] IS NOT NULL
ORDER BY 
    [v].[Aldatsta]

结果:

信息:Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor [4]       已执行ViewResult-视图索引在1540.6805000000002ms中执行。

信息:Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker [2]       在1541.4348毫秒内执行了动作BetaKestrel2.Controllers.BenddController.Index(BetaKestrel2)

信息:Microsoft.AspNetCore.Routing.EndpointMiddleware [1]       执行端点'BetaKestrel2.Controllers.BenddController.Index(BetaKestrel2)'

信息:Microsoft.AspNetCore.Hosting.Diagnostics [2]     请求在1541.8467毫秒内完成 200 text / html; charset = utf-8

在SSMS中

总执行时间124ms

我尝试了AsNoTracking(),但并没有什么不同。您的最后评论使我感到好奇。从查询返回291行,所以我尝试执行.Take(5),执行时间降至 24ms。难道这仅仅是我的foreach循环在视图中占据了所有时间?

1 个答案:

答案 0 :(得分:0)

  

从SSMS查询此视图时,执行时间约为100ms   平均。在我的应用中执行相同的查询时,执行时间   从〜800ms到〜1.5s。

SQL Server Management Studio(SSMS)

  • 未使用RAW SQL

EF实体声誉

放入

var query = 
from p in _context.vWebQuery
where p.Almachine == "BENDD"
orderby p.Aldatsta
select p;

在一个计时块中,将其循环3次并取最后一次。

--create dbContext here. (_context)

--start loop (run 3 times)

    --start timer

var query = ( 
            from p in _context.vWebQuery
           where p.Almachine == "BENDD"
          orderby p.Aldatsta
          select p
        ).Tolist();

    --end timer -this is what you want to compare after the 3 run.
               - yes it will be slower but you could make as non tracking 
               - should be a must fairer comparison.

-- end loop

提示-将其置于调试中,将断点置于索引上...将查询更改为ToList(),以便它在该点执行查询,而不是在视图部分中对其进行修改。

测试代码:已修改

        for (int i = 0; i <= 3; i++)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            var query = (from p in _context.vWebQuery
                         where p.Almachine == "600L"
                         orderby p.Aldatsta
                         select p
            ).ToList();

            stopwatch.Stop();
            Console.WriteLine(stopwatch.ElapsedMilliseconds);
        }
     .....