2016-09-12 1 views
1

次のコードは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(); 
    .... 
    } 
} 

しかし、(私はSQL Serverプロファイラからピックアップ)EFが生成するクエリは、ミリ秒以内に実行されます。

db.Configuration.AutoDetectChangesEnabled = false; 

それdidntのヘルプ:

私は、次のコマンドで変更の追跡を無効にすることを試みました。

2つのIncludesを組み合わせるとクエリが遅くなりますが、そのうちの1つを削除すると即座に結果が返されます。

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' 

任意の提案ですか?

+1

最初の3つの 'AsNoTracking()'呼び出しは何の影響もありません。呼び出しの結果を使用する必要があります。 –

+0

私はそれを試みましたが、違いはありません:/インクルードをRemvoingすることで、ずっと速くなりました。レイジーローディングTEjd_ESRとTMatは10K行では役に立ちません。 – Kenci

+0

また、クエリを投稿できますか? – bubi

答えて

0

私は、パラメータスニッフィングに関するAllan S. Hansenのコメントに同意します。あなたは、部分的に照会

WHERE ([Extent1].[EjdStatus] = @p__linq__0)を持っており、@p__linq__0パラメータが最後にクエリでnvarchar(4000)として渡されます。。[UnionAll1] [EjdId1] ASC、[UnionAll1] [C1] ASC」で

ORDER 、N '@ p__linq__0 のnvarchar(4000)'、@ p__linq__0 = N'HentData」

IはEjdStatus列がデータベース内のnvarchar(4000)のように定義されていないと推測しています。私は、これがデータベースに間違った実行計画またはインデックスを選択させていると考えています。私たちはこの問題を経験しました。私たちは、EFクエリが正しいデータ型を使用し、多くの役に立ちましたことを確認することでした。

は、私たちはデータコンテキストにOnModelCreatingオーバーライドでHasDataTypeメソッドを呼び出すことによって、これをしなかった:これは、EFは、SQLは、適切な実行計画を選択することができ、それが生成するクエリで正しいデータ型を使用せ

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

    //other code here 
} 

関連する問題