8

主な質問 C# linq から実行されたクエリは、他の方法で実行された場合よりも完了するまでに桁違いに時間がかかる可能性があるという事実を説明できる既知の制限、 snafu 、構成の問題などはありますか?

これは、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);

そして、これが生成する(省略/フォーマットされた)SQLです

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 プロファイラーを使用して実行されるクエリの観察に基づいて速度テストを行っています。

この linq クエリが私の C# アプリケーションで通常の操作の一部として実行されると、 IN SITU で、SQL プロファイラーで選択カウントが完了するまでに 3 秒かかり、奇妙なことに、プロジェクションを生成するクエリは 200 ミリ秒しかかからないことがわかります。時間は繰り返し可能であり、クエリ実行プランのキャッシュの問題を除外しているようです。(エンティティ フレームワーク 5、SQL Server 2008 r2 で実行)

IN LINQPAD で、C# アプリケーションの dll のデータ コンテキストを使用して LinqPad を介して linq ステートメントを実行すると、カウントとプロジェクションはそれぞれ 1/4 秒未満で完了します (合計実行時間は 450 ミリ秒あたり 224 ミリ秒まで)。

SSMS では、SQLのソースに関係なく、SQLプロファイルが実行を報告する実際のコードをコピーして管理スタジオウィンドウに貼り付けて実行すると、約224msかかります。

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

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

4

2 に答える 2

8

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

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

于 2013-03-11T16:44:41.487 に答える
2

ARITHABORTは、SSMS では既定で ON であり、SqlClient 接続では既定で OFF です。

問題が再び発生する場合は、次を追加します。

new SqlCommand("SET ARITHABORT ON", connection).ExecuteNonQuery();
于 2013-04-15T16:24:19.247 に答える