SQL Serverクエリキャッシュから特定の不良プランを削除するにはどうすればよいですか?


33

非常に不適切なクエリプランを断続的にキャッシュする1つの特定のSQL Server 2008クエリ(ストアドプロシージャではなく、同じSQL文字列-5分ごとに実行)があります。

このクエリは通常数ミリ秒で実行されますが、この不適切なクエリプランでは30秒以上かかります。

運用データベースサーバー上のクエリキャッシュ全体を吹き飛ばすことなく、SQL Server 2008から1つの不良キャッシュクエリプランのみを外科的に削除するにはどうすればよいですか?


回答:


39

いくつかのことがわかった

select * from sys.dm_exec_query_stats

キャッシュされたすべてのクエリプランが表示されます。残念ながら、そこにはSQLテキストは表示されません。

ただし、次のようにSQLテキストをプランに結合できます。

select plan_handle, creation_time, last_execution_time, execution_count, qt.text
FROM 
   sys.dm_exec_query_stats qs
   CROSS APPLY sys.dm_exec_sql_text (qs.[sql_handle]) AS qt

ここからWHERE、クエリに含まれていることがわかっているSQLを見つけるための句を追加して、実行することができます。

DBCC FREEPROCCACHE (plan_handle_id_goes_here)

クエリプランキャッシュから各クエリプランを削除します。簡単でも便利でもありません、機能しているようです。

編集:クエリキャッシュ全体をダンプすることも機能し、少なくとも私の経験では、思ったより危険ではありません。

DBCC FREESYSTEMCACHE ('ALL') WITH MARK_IN_USE_FOR_REMOVAL;

2
計画のヒントを使用するためのアドバイスはそれでも変わりません。
レムスルサヌ2009

1
クエリが魔法のように更新されて悪い計画だったのでこれを見つけましたが、次回はテストする予定です。クエリが「optional-itis」に悩まされている場合、プランのヒントは役に立たない-多くのオプションパラメータがあり、1つのセットに対して最適化されてから、別のセットで実行される。この種のクエリに添付できる最適なプランはありません。あるパラメーターセットには最適な計画があり、それは別のパラメーターセットにはひどいものです。
Nick.McDermaid

6

良い計画がどのように見えるかを知っているなら、単に計画のヒントを使用してください

特定のキャッシュエントリを削除することはできませんが、を使用してキャッシュプール全体をクリーンアップできますDBCC FREESYSTEMCACHE(cachename/poolname)

あなたは(からの平面ハンドルを持っている場合は、不正なクエリプランのキャッシュ名を取得することができますsys.dm_exec_requests.plan_handle実行中のトラブルでsession_idのための、またはからsys.dm_exec_query_statsポストの実行):

select ce.name
from sys.dm_exec_cached_plans cp
join sys.dm_os_memory_cache_entries ce on cp.memory_object_address = ce.memory_object_address
where cp.plan_handle = @bad_plan

ただし、すべてのSQLプランには「SQLプラン」という名前が付いているため、DBCC FREESYSTEMCACHEに適したプランを選択するのは難しい選択です。

更新

気にせDBCC FREEPROCCACHE(plan_handle)ず、忘れてしまいました、はい、うまくいきます。


1
plan_handleをDBCC FREEPROCCACHEに渡す機能は、SQL Server 2005ではなくSQL Server 2008で使用できます。
マリオ

fromにsys.dm_exec_cached_plansエントリがない場合はどういう意味ですか?plan_handlesys.dm_exec_requests
ジョナサンギルバート

@JonathanGilbertは、プランがキャッシュされなかったか、キャッシュから削除されたことを意味します。docs.microsoft.com/en-us/sql/relational-databases/…を
Remus Rusanu

確認するために、クエリを実行し始めたばかりなのにで、クエリにキャッシュしないことを示すヒントがありませんが、SQL Serverがキャッシュしないという値を決定したため、キャッシュを解除できますか?まだ実行されているからではありませんよね?プランをキャッシュすることを決定した場合、クエリ実行を開始するポイントからすぐにキャッシュされますか?
ジョナサンギルバート

1

FREEPROCCACHEのソリューションは結構ですが、これを行うためのより直接的な方法は、使用することですOPTION(RECOMPILE)をおそらくあなたが疑われるので、これはエンジンにそのシングルユース計画を伝え、(あなたはそれがSPではなかった言及した)あなたのSQL文字列にパラメータスニッフィングがあるか、統計が実行ごとに大幅に異なるため、キャッシュプランの問題が疑われます。

DECLARE @SQL NVARCHAR(4000)
SELECT @SQL = 'SELECT * FROM Table WHERE Column LIKE @NAME OPTION (RECOMPILE)'
EXEC sp_executesql @SQL, N'@NAME varchar(15)', 'MyName' 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.