2011-08-19 13 views
5

最近パフォーマンスの問題がありましたが、これはDBCC freeproccacheを実行することで解決しました...今、私たちはもっと多くの質問に答えます。DBCC freeproccache?

  • 何がプロシージャキャッシュを期限切れにしましたか?
  • インデックスまたは統計情報の日付が間違っている場合、クエリで が再コンパイルされなかったのはなぜですか?
  • DBCC freeproccacheをジョブとしてスケジュールするのは良い方法ですか?
  • 期限切れのクエリプランを特定する方法はありますか?
  • 問題のあるクエリを特定する方法はありますか?

ご了承ください。

+0

使用しているSQL Serverのバージョンを確認してください。 [タグ:sql-server-2005]、[タグ:sql-server-2008] ... –

+2

すべての 'DBCC freeproccache'はプロシージャキャッシュを空にします。統計が更新されることはありません。逆に、統計が自動更新されると、プランは再コンパイルされます。私はあなたがクエリのキャッシュにあった計画がすべての可能なパラメータ値に適していなかったパラメータスニッフィングの問題があったと仮定します。 –

+0

私はSQL Server 2005を使用しています! – user173552

答えて

8

あなたの質問はすべての場所にあるので、私はすべてそれらに対処しようとします。プロシージャキャッシュは非常に大きいです。プロシージャキャッシュには1回限りのプランが設定されている可能性があります(これは統計には影響しませんが、統計はプランキャッシュに影響する可能性があります)。 Kimberly Trippのブログ記事 "Plan cache and optimizing for adhoc workloads"のシングルユースプランに関する詳細を読むことができます。これにはsys.dm_exec_cached_plansに対するクエリが含まれています。これは、キャッシュに多くの使い捨てプランが設定されていることを確認するのに役立ちます。彼女が示唆しているように、アドホックワークロードに最適化を使用することで、この膨張を防ぐことができます。あなたがこれを頻繁に行う必要があることを知っているなら、仕事としてのfreeproccacheのスケジューリングは解決策ではなく、バンドエイドであると言います。

「悪い」計画をクリアするには、まず「悪い」計画を特定する必要があります。これは、特定のサイズを超えるプランや、実行されていないプラン、または長期間実行されたクエリなどによって特定されたプランです。残念ながら、パラメータの犠牲者であるプランを特定するのは簡単ではありません影響を受けるクエリを既に知っていない限り、スニッフィングします。あなたが一週間以上で実行されていないキャッシュ内の最も古い計画を見つけたいとしましょう:

;WITH x AS 
(
    SELECT TOP 10 
     qs.[sql_handle], qs.plan_handle, 
     txs = qs.statement_start_offset, 
     txe = qs.statement_end_offset, 
     [size] = cp.size_in_bytes, 
     [uses] = SUM(cp.usecounts), 
     [last] = MAX(qs.last_execution_time) 
    FROM 
     sys.dm_exec_query_stats AS qs 
    INNER JOIN 
     sys.dm_exec_cached_plans AS cp 
     ON qs.plan_handle = cp.plan_handle 
    WHERE 
     qs.last_execution_time < DATEADD(DAY, -7, CURRENT_TIMESTAMP) 
    GROUP BY 
     qs.[sql_handle], qs.plan_handle, cp.size_in_bytes, 
     qs.statement_start_offset, qs.statement_end_offset 
    ORDER BY 
     [size] DESC 
) 
SELECT 
    x.plan_handle, 
    size, uses, [last], 
    [statement] = COALESCE(NULLIF(
     SUBSTRING(t.[text], x.txs/2, 
      CASE WHEN x.txe = -1 THEN 0 ELSE (x.txe - x.txs)/2 END 
     ), ''), t.[text]) 
FROM x 
CROSS APPLY sys.dm_exec_sql_text(x.[sql_handle]) AS t; 

今、あなたはあなたが本当にこの計画をクリアすることを確認する必要があります。たとえば、そのクエリーが明日実行されるかもしれないものとしてそのクエリーを認識したら、それをそこに残すことが最善の方法かもしれません。

DBCC FREEPROCCACHE([paste plan handle from above query here]); 

は、これは世界的にDBCC FREEPROCCACHEを実行しているよりも多くの仕事のように聞こえるが、あなたは、キャッシュ内の良い計画の多くを持っている場合、:あなたが計画をクリアしたい場合は、言って、直接それをクリアすることができますユーザー全体にとっては確かに優れているはずです。

まだ、これは本当にバンドエイドのようです。あなたのキャッシュがジャンクでいっぱいになり、キャッシュを解放するまでパフォーマンスがトイレに入ると、アーキテクチャの上位レベル、クエリの送信方法などを調べる必要があります。これは私が期待している動作ですLINQ2SQLの最初の反復で、異なる長さの各文字列引数のクエリの計画のバージョンをキャッシュします。したがって、 'January'のパラメータがある場合は、VARCHAR(7)VARCHAR(8)のデータ型を定義するため、 'February'のパラメータとは異なるプランを取得します。動作が固定されていることを確かめてくださいが、あなたの環境/アプリケーションについて十分にわからないので、「悪いアイデア」を正確に探す場所を示唆していません。

+0

アドホックワークロードの最適化を無視します。これはSQL Server 2008で導入されました。 –

関連する問題