回答:
クエリチューニング101
クエリのチューニングに魔法のような特効薬はありませんが、いくつかのヒントを提供できます。最初にすることは、舞台裏で実際に何が起こっているかを理解することです。3番目の達人のガイドブックのような良い内部の本を入手してください。
パフォーマンスの低いクエリには、2つの基本的な特性があります。トランザクションクエリには時間がかかりすぎ、バッチジョブ(またはレポート)には時間がかかりすぎます。問題のあるクエリの良い兆候の1つは、クエリプラン内の1つのアイテムが99%の時間を費やすことです。
トランザクションクエリ
ほとんどの場合、トランザクションクエリのパフォーマンスの低下は、いくつかのことの1つです。
インデックスがありません。これはクエリプランで見ることができます-非常に選択的(つまり、いくつかの行を返す)である必要がある結合の大きなテーブルのテーブルスキャン。
クエリはインデックスを使用できません。where句にOR条件があり、計算値またはsarg可能でないクエリ内の他のアイテムに結合する場合、クエリを書き直す必要があります。簡単に言うと、sargsは、インデックスを使用して行を削除できるクエリ述語です。論理AND、等式および不等式(>、> =、<、<=および!=)はすべてsarg可能です。ORは伝統的にsarg可能ではありません。ただし、ORからNOT(fooおよびnot bar)型の構造に意味を逆にすることにより、ORをsarg-able述語に変換することができます。
非効率的な述語。たとえばwhere in
、ネストされたサブクエリを参照している場合where exists
、結合として、または結合として書き換えられるかどうかを確認します。これにより、クエリプランがより効率的になる可能性があります。また、他の標準的な書き直しも試してみてください。繰り返しになりますが、教科書のガイドブックやその他のテーマについては、良い出発点です。
バッチクエリ
バッチクエリはより複雑で、チューニングの問題が異なります。いくつかのヒントは次のとおりです。
インデックス作成。これは、トランザクションクエリの場合と同じ理由で大きな違いを生む可能性があります。多くの場合、インデックスが欠落していることを示す良い兆候は、マシンをスラッシングしているようには見えない長時間の研削操作(クエリプランの99%)です。
一時テーブル。クエリを一時テーブルに入力するいくつかのクエリに分割する方が適切な場合があります。クエリが大きくなると、オプティマイザーは問題を起こす余地が増えますが、これは以前ほど問題ではなくなりました。select into
この操作は最小限のログしか記録されないため(ログアクティビティがはるかに少ない)、一時テーブルを作成し、I / Oの負荷を軽減します。
tempdbの一時テーブルは、オプティマイザーが中間結合結果を格納するために使用するものと同じデータ構造であるため、これを行うことによるパフォーマンスの低下はありません。一時テーブルにインデックス(クラスター化インデックスとカバーインデックスを含む)を作成することもできます。これにより、静的テーブルのクエリが改善されるのと同じ理由で、インデックスを読み取るクエリのパフォーマンスが向上する場合があります。
ただし、一時テーブルを無理にしないでください。クエリをさかのぼることが難しくなります。ストアドプロシージャ内の小さなテーブルの場合、テーブル変数が役立つかどうかをテストします。これらはインメモリデータ構造であるため、パフォーマンスが向上する可能性があります。
クラスター化インデックスとカバリングインデックス。これらは、グループ化列に基づいてディスク上の参照の局所性を強制するため、クエリのパフォーマンスを改善できます。クラスタ化インデックスは、バッチジョブのパフォーマンスに大きな違いをもたらす可能性があります。
非効率的な述語。これらは、トランザクションクエリの場合とほぼ同じ方法で、sargsや他の準最適化問題で問題を引き起こす可能性があります。
テーブルスキャンはあなたの友達です。一般的な考えに反して、テーブルスキャンは本質的に悪ではありません。一般に、トランザクションクエリで何か間違っている兆候ですが、大規模なバッチ操作を行う最も効率的な方法であることがよくあります。テーブル内の数パーセント以上の行を使用して何かを実行している場合、テーブルスキャンは多くの場合、テーブルをカバーする最も効率的な方法です。
ネストされたループが結合します。オプティマイザーが参加の両側で何をしているのか見てみましょう。これらは、たとえば、ネストされたループ結合の両側にある2つの大きなテーブルをスキャンするテーブルです。クラスター化インデックスの使用を検討order by
するか、片側がハッシュ結合を促進するために操作をマージ結合またはヒントに変更することを検討してくださいこれを行うには十分に小さい。
ロッキング
ロックはパフォーマンスの問題も引き起こす可能性があります。システムが負荷のかかった状態でパフォーマンスが低下している場合は、ロックに関連するプロファイラーとperfmonカウンターを調べ、重大な競合がないかどうかを確認します。 sp_who2
結果セットに「BlkBy」列があり、クエリがブロックされているかどうか、およびブロックされているものが表示されます。また、「デッドロックグラフ」イベント(クエリにデッドロックが発生している場合)およびロック関連のイベントを含むプロファイルは、ロックの問題のトラブルシューティングに役立ちます。
SQL Server実行計画の操作方法と理解方法に関するRedGateの優れた無料の電子ブック
http://www.red-gate.com/specials/Grant.htm?utm_content=Grant080623
Shameless Plug、私はブログのSQL Server Performanceでパフォーマンスチューニング資料を参照しています。
この資料の一部を消化する機会がありましたら、ここに投稿するか、特定の質問を直接私に連絡してください。
まず、インデックス作成。多くの人は、外部キーがインデックスを自動的に取得しないことに気付いていません。結合で使用されるため、ほとんどの場合、インデックスが必要です。
すべてのカーソルを綿密に調べて、代わりにセットベースのコードで置き換えることができるかどうかを確認してください。これを行うことで、数時間実行するコードを数秒に変更しました。
サブクエリを避けます。コード内にある場合は、結合または派生テーブルへの結合に置き換えます。
where句がsargeableであることを確認してください。
実行計画を読むことを学ぶ。
オフィスにパフォーマンスチューニングに関する優れた書籍がいくつかあることを確認してください。
テーブル変数は、一部のインスタンスでは一時テーブルよりも優れており、他のインスタンスでは一時テーブルのパフォーマンスが向上しています。それらを使用する必要がある場合は、両方を試して、特定のケースでどちらがうまく機能するかを確認してください。