7

MAIN QUESTION すべてのものが等しいこと、C#linqから実行されたクエリが注文を取ることができるという事実を説明することができる既知の制限他の方法で実行した場合よりも完了までに時間がかかりますか?LINQクエリはSSMSに比べて非常に遅い

ここでは、linqの省略形です。それはビューとテーブルの間の非常に単純な前方結合です。ここ

var query = (
    from content in context.ApprovedContentView 
       where content.BucketId == 13098 && content.ContentTypeId == 5220 
    join item in context.ActiveContent 
       on content.ContentId equals item.ItemId 
     where 
       item.IsSuchAndSuch == true && item.SomeOtherProperty == 5000 
     select new 
     { 
      ItemId = item.ItemId, 
      Title = item.Title, 
      SubTitle = item.SubTitle, 
      DescriptionText = item.DescriptionText, 
      /* about 10 other scalar fields */ 

     }); 

int count = query.Count(); 
var data = query.OrderByDescending(item => item.ItemId).Skip(5).Take(3); 

そしてそれは

SELECT 
[GroupBy1].[A1] AS [C1] 
FROM (SELECT 
    COUNT(1) AS [A1] 
    FROM  [SchemaX].[ApprovedContentView] AS [Extent1] 
    INNER JOIN [SchemaX].[ActiveContent] AS [Extent2] ON [Extent1].[ContentId] = [Extent2].[ItemId] 
    WHERE (13098 = [Extent1].[BucketId]) AND (5220 = [Extent1].[ContentTypeId ]) AND 
    (1 = [Extent2].[IsSuchAndSuch]) AND (5000 = [Extent2].[SomeOtherProperty ]) 
) AS [GroupBy1] 
GO 

SELECT TOP (3) 
[Filter1].[BucketId] AS [BucketId], 
[Filter1].[ItemId] AS [ItemId], 
[Filter1].[Title] AS [Title], 
[Filter1].[SubTitle] AS [SubTitle], 
[Filter1].[DescriptionText] AS [DescriptionText], 
/* other fields */ 
FROM (SELECT 
      [Extent1].[BucketId] AS [BucketId], 
      [Extent2].[ItemId] AS [ItemId], 
      [Extent2].[Title] AS [Title], 
      [Extent2].[SubTitle] AS [SubTitle], 
      [Extent2].[DescriptionText] AS [DescriptionText], 
      /* other fields */ 
      row_number() OVER (ORDER BY [Extent2].[DealId] DESC) AS [row_number] 
    FROM [SchemaX].[ApprovedContentView] AS [Extent1] 
    INNER JOIN [SchemaX].[ActiveContent] AS [Extent2] ON [Extent1].[ContentId] = [Extent2].[ItemId] 
    WHERE (13098 = [Extent1].[BucketId]) AND (5220 = [Extent1].[ContentTypeId ]) AND 
      (1 = [Extent2].[IsSuchAndSuch]) AND (5000 = [Extent2].[SomeOtherProperty ]) 
) AS [Filter1] 
WHERE [Filter1].[row_number] > 5 
ORDER BY [Filter1].[DealId] DESC 

異なるシナリオ 私は、クエリを観察する上で、私の速度のテストを基づかています、その場でのSQLプロファイラ

を使用して実行を生成する(略し/ formmatted)SQLです このlinqクエリがC#アプリケーションで通常の操作の一部として実行されるとき、私はSQLプロファイラでselect countが3秒間cオププット、および奇妙なことに、投影を生成するクエリにはわずか200ミリ秒しかかからず、その時間は繰り返し実行されます。これはクエリ実行プランのキャッシュ問題を排除するようです。私はC#アプリケーションのDLLのデータコンテキストを使用して、LinqPadを通じてLINQ文を実行LINQPAD 、数および四半期の下で完全な投影それぞれで (エンティティフレームワーク5は、SQL Server 2008 R2を実行している)

秒(約224ms、合計実行時間約450ms)。私はそれを実行し、管理スタジオウィンドウに貼り付けて実行することを、プロファイルのレポートをSQL実際のコードをコピーするときSSMS、IN

は関係なく、SQLのソースの、それはおよそ224msかかります。 SSMSで をチューニング

データベース、私はプロファイラ(コードからまたはlinqpadからのいずれか)からコピーSQLの実際の実行計画を評価するとき、私はSQLはすべて正しいインデックスを使用している、と報告していることがわかりますインデックスシークのみ - テーブルスキャンなし、リッドルックアップなし。

だから、何ができますか?誰もこれのようなものを見たことがありますか?

+0

おそらく古くなって、キャッシュされた実行計画を持っていますか?なぜあなたはあなたのアプリからそれをヒットしたときにあなただけを参照してください説明するかもしれない。 – FlyingStreudel

+0

返す行数はいくつですか?これがアプリケーションの最初のクエリですか? – ken2k

答えて

5

あなたのアプリケーション用にキャッシュされている不良実行プランがないことを確認します。これは、既に使用されているデータベースでスキーマ作業を行うときによく起こります。 SSMSクエリに対して生成された実行計画が最新であり、これらのパフォーマンスの問題が見られない間に、スキーマの変更によって非効率なアプリケーション実行コンテキスト用にキャッシュされた実行計画がある可能性があります。

DBCC FREEPROCCACHEを使用して実行計画の更新を強制し、問題が解決するかどうかを確認します。

+0

これはログ・ジャムを壊したように見えます。ありがとうございました!! – groggyjava

+0

これは私のために働いた。私のローカルデータベースに対して実行された同じクエリは、一貫してEFで44秒かかりました。プロファイラでクエリを取得してSSMSで実行したところ、1秒未満で完了していました。私は両者の間を行き来し、両方で同じクエリを実行しました。これらの驚異的な実行時の違いは一貫していました。 DBCC FREEPROCCACHEを実行した直後に、両方のクエリが1秒未満で実行されていました。 – Triynko

0

ARITHABORTは、SSMSではデフォルトでオンになっており、SqlClient接続ではデフォルトでオフになっています。

問題が現れた場合は、再び追加します。

new SqlCommand("SET ARITHABORT ON", connection).ExecuteNonQuery();