[あいさつ]
(1つチェック)
[ ] Well trained professional, [ ] Casual reader, [ ] Hapless wanderer,
(該当するものをすべてチェックしてください)
[ ] query [ ] stored procedure [ ] database thing maybe
それはうまくいっていました(該当する場合)
[ ] yesterday [ ] in recent memory [ ] at some point
今は急に遅くなっています。
ブロックされていないこと、および長時間実行されているメンテナンスタスク、レポート、またはその他の帯域外プロセスの被害を受けていないことを確認しました。
何が問題なのか、何をすべきか、そして何らかの助けを得るためにどのような情報を提供できますか?
[*Insert appropriate closing remarks*]
[ここにあなたの名前]様!
ああ、ごめんなさい! Jiffyで修正するための基本から始めましょう。
これは、奇抜で奇妙な問題を解決する方法です。その名は舌から転がり落ちる。リスのドイツ語のように。
そしてそれは通常あなたの友達です。
クエリがサーバーに到達したら、プランをコンパイルする必要があります。時間とリソースを後で節約するために、実行プランは、パラメーターによってコードが処理されて返される推定行に基づいてキャッシュされます。
これがうまくいかないことを想像する最も簡単な方法は、偏った2つの母集団から物事を数える必要があるストアドプロシージャを想像することです。
例えば:
負傷していないCrossFitシャツを着ている人:ゼロ
ひるむときにひるむCrossFitシャツを着ている人:すべて
明らかに、そのコードの1回の実行では、別の実行よりも多くの作業を行う必要があり、まったく異なる量の作業を実行するクエリプランは、まったく異なって見えます。
これは、発見、テスト、修正が本当に難しい問題です。
場合によっては、必要なのは少し明快です。むしろ、あなたの計画キャッシュはそうします。
EXEC sys.sp_recompile @objname = N'schema.procname'
を実行してみてください。これにより、次に実行するときにプロシージャが新しいプランを再コンパイルします。
これで修正されないもの:
これが保証しないもの:
sp_recompile
をテーブルまたはビューにポイントすることもできますが、そのテーブルまたはビューに関連するすべてのコードが再コンパイルされることに注意してください。これは問題をかなり難しくするかもしれません。
あなたの仕事はもう少し難しいです。 SQLハンドルを追跡する必要があります。プランキャッシュ全体を解放する必要はありません。テーブルまたはビューに対してsp_recompile
を使用するのと同じように、意図しない結果の全体をトリガーすることができます(ハハハ)。
このコマンドを理解する最も簡単な方法は、 sp_BlitzWho *を実行することです。キャッシュから単一のプランを削除するコマンドを含む「fix parameter sniffing」と呼ばれる列があります。ただし、これには再コンパイルと同じ欠点があります。
これで修正されないもの:
これが保証しないもの:
次のものが必要です。
クエリが実行中の場合、 sp_BlitzWho *または sp_WhoIsActive を使用して、現在実行中のクエリをキャプチャできます。
EXEC sp_BlitzWho;
EXEC sp_WhoIsActive @get_plans = 1;
クエリが現在実行されていない場合は、 sp_BlitzCache *を使用して、プランキャッシュでクエリを確認できます。
SQL Server 2016以降を使用していて、クエリストアをオンにしている場合は、 sp_BlitzQueryStore *を使用できます。
EXEC dbo.sp_BlitzCache @StoredProcName = 'Your Mom';
EXEC dbo.sp_BlitzQueryStore @StoredProcName = 'Your Mom';
これらは、ストアドプロシージャのキャッシュされたバージョンを追跡するのに役立ちます。パラメータ化されたコードだけの場合、検索は少し難しくなります。しかし、これは役立つかもしれません:
EXEC dbo.sp_BlitzCache @QueryFilter = 'statement';
これらのいずれからもかなり類似した出力が表示されるはずです。繰り返しになりますが、クールで青いクリック感のある列を招くクエリプランは、あなたの友達です。
プランを共有する最も簡単な方法は、 Paste The Plan *を使用するか、XMLをPastebinにダンプすることです。それを取得するには、青いクリックしやすい列が表示されているいずれかをクリックします。クエリプランが新しいSSMSタブに表示されます。
会社のコードとクエリを共有することに不満がある場合は、 Sentry Oneの無料のプランエクスプローラーツール を使用してプランを匿名化できます。覚えておいてください、これは助けを得ることを難しくします-匿名化されたコードは読んで理解するのがはるかに難しくなります。
話し合ったこれらのツールはすべて、クエリテキストを返すはずです。ここでは他に何もする必要はありません。
パラメータの取得はもう少し難しいです。 プランエクスプローラー を使用している場合は、下部にタブがあり、すべてが一覧表示されます。
sp_BlitzCache *を使用している場合は、ストアドプロシージャの実行ステートメントを提供するクリック可能な列があります。
SSMSで簡単に右クリックして、スクリプトを作成できます。
すべてを一度に取得したい場合は、テーブルを直接指すと、 sp_BlitzIndex *が役立ちます。
EXEC dbo.sp_BlitzIndex @DatabaseName = 'StackOverflow2010',
@SchemaName = 'dbo',
@TableName = 'Users';
これにより、テーブル定義(createステートメントとしてではありません)、およびすべてのインデックスのcreateステートメントが提供されます。
この情報を収集して質問に追加すると、人々に役立つ十分な情報が提供されるか、正しい方向に向けられるはずです。
まあ、かっこいい。嬉しいです。あなたは狂った人です。
パラメータスニッフィングを「修正」すると人々が考える方法はたくさんあります。
しかし、これらは実際には、さまざまな方法でパラメータースニッフィングを無効にするだけです。彼らが問題を解決できないと言っているのではなく、根本的な原因を突き止めていないだけです。
根本的な原因に到達することは、通常、一種の難しいからです。あなたはそれらの厄介な「計画の品質の問題」を探す必要があります。
高速プランと低速プランから始めて、次のような違いを探します。
また、コードをパラメータスニッフィングに敏感にするさまざまな演算子を探します。
シークVSスキャン、インデックスの断片化、または人々が裾を回って見回す貨物のカルティカルなものに巻き込まれないでください。
通常、かなり基本的な索引付けの問題があります。時々、コードは少し書き直す必要があります。
パラメータスニッフィングについて詳しく知りたい場合:
アプリケーションで遅い、SSMSで速い? -Erland Sommarskog
プロのようなパラメーターを使用してパフォーマンスを向上させる方法 -Guy Glantser
パラメータスニッフィング、埋め込み、およびRECOMPILEオプション -ポールホワイト
これを読んでいて、リンクや役立つツールを見逃したと思われる場合は、コメントを残してください。これを最新の状態に保つために最善を尽くします。
クエリのパフォーマンスが変動する原因として考えられるのは、パラメータスニッフィングだけではありません。次の一般的な理由のいずれかが同じ症状を示す可能性があります。
このリストの項目6〜11は、何らかの明示的なアクションが実行された後にのみ発生します。あなたはそれらを除外するつもりだったと思いますが、多くの場合、チャレンジを経験している人は他の誰かが変更を加えたことに気づいていないため、プランのキャッシュエントリをクリアする方法に進む前に確認する価値があります。
答えがわからない場合に備えて既存の回答に追加するために、クエリが翌日に「突然」異なる動作をする場合は、以下を確認してください。
Reports → Standard Reports → Schema Changes History
を選択できます。もう1つの可能性は、インフラストラクチャチームがVMware上のvMotionなどのツールを使用しており、SQLインスタンスをサポートするVMが、DBAに気付かれずにシームレスにホストからホストに移動されていることです。
インフラストラクチャが外部委託されている場合、これは本当の問題です...私は本当の悪夢を抱えています。