簡體   English   中英

實體框架超時但是從分析器查詢在毫秒內執行

[英]Entity Framework times out but query from profiler executes within milliseconds

以下代碼在60秒后超時。 它應該返回10K行以用於只讀目的:

using (var db = new TUdvEntities(_connectionString))
{
    try
    {
        db.Set<TEjendom>().AsNoTracking();
        db.Set<TEjd_ESR>().AsNoTracking();
        db.Set<TMat>().AsNoTracking();

        IQueryable<TEjendom> query = db.TEjendom;

        foreach (var propertyId in propertiesInProgress)
        {
            query = query.Where(x => x.EjdId != propertyId);
        }

        var description = propertyState.GetDescription();

        var resultListTmp = query.Where(x => x.EjdStatus == description)
            .Include(nameof(TEjd_ESR))
            .Include(nameof(TMat))
            .Take(amount).ToList();
    ....
    }
}

但是,EF生成的查詢(我從SQL Server Profiler中獲取)在一毫秒內執行。

我嘗試使用以下命令禁用更改跟蹤:

db.Configuration.AutoDetectChangesEnabled = false;

但那並沒有幫助。

兩個包含的組合會減慢查詢速度,但是當我刪除其中一個時,它會返回即時結果。

SQL查詢:

exec sp_executesql N'SELECT 
    [UnionAll1].[EjdId] AS [C1], 
    [UnionAll1].[EjdId1] AS [C2], 
    [UnionAll1].[EjdType] AS [C3], 
    [UnionAll1].[BNummer] AS [C4], 
    [UnionAll1].[TNummer] AS [C5], 
    [UnionAll1].[ANummer] AS [C6], 
    [UnionAll1].[ENummer] AS [C7], 
    [UnionAll1].[Beskrivelse] AS [C8], 
    [UnionAll1].[SBT] AS [C9], 
    [UnionAll1].[EjdStatus] AS [C10], 
    [UnionAll1].[StatusTimestamp] AS [C11], 
    [UnionAll1].[IAbo] AS [C12], 
    [UnionAll1].[AOAttempts] AS [C13], 
    [UnionAll1].[AboId] AS [C14], 
    [UnionAll1].[BFE] AS [C15], 
    [UnionAll1].[UpdateToken] AS [C16], 
    [UnionAll1].[FEJ] AS [C17], 
    [UnionAll1].[C1] AS [C18], 
    [UnionAll1].[ESRId] AS [C19], 
    [UnionAll1].[EjdId2] AS [C20], 
    [UnionAll1].[Passiv] AS [C21], 
    [UnionAll1].[EjdId3] AS [C22], 
    [UnionAll1].[C2] AS [C23], 
    [UnionAll1].[C3] AS [C24], 
    [UnionAll1].[C4] AS [C25], 
    [UnionAll1].[C5] AS [C26]
    FROM  (SELECT 
        CASE WHEN ([Extent2].[ESRId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1], 
        [Limit1].[EjdId] AS [EjdId], 
        [Limit1].[EjdId] AS [EjdId1], 
        [Limit1].[EjdType] AS [EjdType], 
        [Limit1].[BNummer] AS [BNummer], 
        [Limit1].[TNummer] AS [TNummer], 
        [Limit1].[ANummer] AS [ANummer], 
        [Limit1].[ENummer] AS [ENummer], 
        [Limit1].[Beskrivelse] AS [Beskrivelse], 
        [Limit1].[SBT] AS [SBT], 
        [Limit1].[EjdStatus] AS [EjdStatus], 
        [Limit1].[StatusTimestamp] AS [StatusTimestamp], 
        [Limit1].[IAbo] AS [IAbo], 
        [Limit1].[AOAttempts] AS [AOAttempts], 
        [Limit1].[AboId] AS [AboId], 
        [Limit1].[BFE] AS [BFE], 
        [Limit1].[UpdateToken] AS [UpdateToken], 
        [Limit1].[FEJ] AS [FEJ], 
        [Extent2].[ESRId] AS [ESRId], 
        [Extent2].[EjdId] AS [EjdId2], 
        [Extent2].[Passiv] AS [Passiv], 
        [Extent2].[EjdId] AS [EjdId3], 
        CAST(NULL AS int) AS [C2], 
        CAST(NULL AS varchar(1)) AS [C3], 
        CAST(NULL AS varchar(1)) AS [C4], 
        CAST(NULL AS int) AS [C5]
        FROM   (SELECT TOP (10416) 
            [Extent1].[EjdId] AS [EjdId], 
            [Extent1].[EjdType] AS [EjdType], 
            [Extent1].[BNummer] AS [BNummer], 
            [Extent1].[TNummer] AS [TNummer], 
            [Extent1].[ANummer] AS [ANummer], 
            [Extent1].[ENummer] AS [ENummer], 
            [Extent1].[Beskrivelse] AS [Beskrivelse], 
            [Extent1].[SBT] AS [SBT], 
            [Extent1].[EjdStatus] AS [EjdStatus], 
            [Extent1].[StatusTimestamp] AS [StatusTimestamp], 
            [Extent1].[IAbo] AS [IAbo], 
            [Extent1].[AOAttempts] AS [AOAttempts], 
            [Extent1].[AboId] AS [AboId], 
            [Extent1].[BFE] AS [BFE], 
            [Extent1].[UpdateToken] AS [UpdateToken], 
            [Extent1].[FEJ] AS [FEJ]
            FROM [dbo].[TEjendom] AS [Extent1]
            WHERE ([Extent1].[EjdStatus] = @p__linq__0) OR (([Extent1].[EjdStatus] IS NULL) AND (@p__linq__0 IS NULL)) ) AS [Limit1]
        LEFT OUTER JOIN [dbo].[TEjd_ESR] AS [Extent2] ON [Limit1].[EjdId] = [Extent2].[EjdId]
    UNION ALL
        SELECT 
        2 AS [C1], 
        [Limit2].[EjdId] AS [EjdId], 
        [Limit2].[EjdId] AS [EjdId1], 
        [Limit2].[EjdType] AS [EjdType], 
        [Limit2].[BNummer] AS [BNummer], 
        [Limit2].[TNummer] AS [TNummer], 
        [Limit2].[ANummer] AS [ANummer], 
        [Limit2].[ENummer] AS [ENummer], 
        [Limit2].[Beskrivelse] AS [Beskrivelse], 
        [Limit2].[SBT] AS [SBT], 
        [Limit2].[EjdStatus] AS [EjdStatus], 
        [Limit2].[StatusTimestamp] AS [StatusTimestamp], 
        [Limit2].[IAbo] AS [IAbo], 
        [Limit2].[AOAttempts] AS [AOAttempts], 
        [Limit2].[AboId] AS [AboId], 
        [Limit2].[BFE] AS [BFE], 
        [Limit2].[UpdateToken] AS [UpdateToken], 
        [Limit2].[FEJ] AS [FEJ], 
        CAST(NULL AS int) AS [C2], 
        CAST(NULL AS int) AS [C3], 
        CAST(NULL AS bit) AS [C4], 
        CAST(NULL AS int) AS [C5], 
        [Extent4].[EjdId] AS [EjdId2], 
        [Extent4].[LeKode] AS [LeKode], 
        [Extent4].[MatNummer] AS [MatNummer], 
        [Extent4].[EjdId] AS [EjdId3]
        FROM   (SELECT TOP (10416) 
            [Extent3].[EjdId] AS [EjdId], 
            [Extent3].[EjdType] AS [EjdType], 
            [Extent3].[BNummer] AS [BNummer], 
            [Extent3].[TNummer] AS [TNummer], 
            [Extent3].[ANummer] AS [ANummer], 
            [Extent3].[ENummer] AS [ENummer], 
            [Extent3].[Beskrivelse] AS [Beskrivelse], 
            [Extent3].[SBT] AS [SBT], 
            [Extent3].[EjdStatus] AS [EjdStatus], 
            [Extent3].[StatusTimestamp] AS [StatusTimestamp], 
            [Extent3].[IAbo] AS [IAbo], 
            [Extent3].[AOAttempts] AS [AOAttempts], 
            [Extent3].[AboId] AS [AboId], 
            [Extent3].[BFE] AS [BFE], 
            [Extent3].[UpdateToken] AS [UpdateToken], 
            [Extent3].[FEJ] AS [FEJ]
            FROM [dbo].[TEjendom] AS [Extent3]
            WHERE ([Extent3].[EjdStatus] = @p__linq__0) OR (([Extent3].[EjdStatus] IS NULL) AND (@p__linq__0 IS NULL)) ) AS [Limit2]
        INNER JOIN [dbo].[TMat] AS [Extent4] ON [Limit2].[EjdId] = [Extent4].[EjdId]) AS [UnionAll1]
    ORDER BY [UnionAll1].[EjdId1] ASC, [UnionAll1].[C1] ASC',N'@p__linq__0 nvarchar(4000)',@p__linq__0=N'HentData'

有什么建議么?

我同意Allan S. Hansen關於參數嗅探的評論。

您查詢的部分是WHERE ([Extent1].[EjdStatus] = @p__linq__0) ,並且@p__linq__0參數在結尾的查詢中作為nvarchar(4000)傳入:

ORDER BY [UnionAll1]。[EjdId1] ASC,[UnionAll1]。[C1] ASC',N'@ p__linq__0 nvarchar(4000) ',@ p__linq__0 = N'HentData'

我猜測EjdStatus列未在數據庫中定義為nvarchar(4000)。 我相信這會使數據庫選擇錯誤的執行計划或索引。 我們遇到了這個問題,我們所做的是確保EF查詢使用了正確的數據類型並且幫助了很多。

我們通過在數據上下文中的OnModelCreating覆蓋中調用HasDataType方法來完成此OnModelCreating

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<MyClass>().Property(a => a.EjdStatus).HasColumnType("VARCHAR");

    //other code here
}

這導致EF在其生成的查詢中使用正確的數據類型,這允許Sql選擇適當的執行計划。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM