SQL Server 2005/8クエリ最適化のヒント


13

私は、より良いSQL Serverクエリを作成することについてチームを教育することを検討しており、パフォーマンスを向上させるための最良のヒントは何であるかと考えていました。

たとえば、count(*)がcount(1)よりもパフォーマンスが悪いと主張するDBAがいました(彼女が正しいかどうか、または最新のクエリオプティマイザーに対してまだ有効かどうかはわかりません)。

どのような単純なことをチームに伝えて、常に使用または回避を試みるべきですか?私は理想的には、(a)合理的な違いを生む可能性があり、(b)明言するために1-2行であるものを探しています。

回答:


13

クエリチューニング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」列があり、クエリがブロックされているかどうか、およびブロックされているものが表示されます。また、「デッドロックグラフ」イベント(クエリにデッドロックが発生している場合)およびロック関連のイベントを含むプロファイルは、ロックの問題のトラブルシューティングに役立ちます。


1
これはパフォーマンスチューニングに関する素晴らしい情報であるため、+ 1です(Kalenのクラスに参加できたことを嬉しく思いました。彼女は自分が何をしているのか知っています!)。動的ビューに関する情報を追加するだけで済みます。
ウェイン

3

最良のヒント:SQL Server 2008を使用し、テストの実行中にアクティビティモニターを実行します。最も時間がかかる/ I / Oが最も多いクエリなどに注意してください。これらのクエリを右クリックして、クエリや実行プランを表示します。

次:実行計画を理解することを学びます。

次:データベースチューニングウィザードを使用します。

これらの手順は、独自の「最良のヒント」を生成するのに役立ちます。


2

SQL Server実行計画の操作方法と理解方法に関するRedGateの優れた無料の電子ブック

http://www.red-gate.com/specials/Grant.htm?utm_content=Grant080623

Shameless Plug、私はブログのSQL Server Performanceでパフォーマンスチューニング資料を参照しています

この資料の一部を消化する機会がありましたら、ここに投稿するか、特定の質問を直接私に連絡してください。


1

まず、インデックス作成。多くの人は、外部キーがインデックスを自動的に取得しないことに気付いていません。結合で使用されるため、ほとんどの場合、インデックスが必要です。

すべてのカーソルを綿密に調べて、代わりにセットベースのコードで置き換えることができるかどうかを確認してください。これを行うことで、数時間実行するコードを数秒に変更しました。

サブクエリを避けます。コード内にある場合は、結合または派生テーブルへの結合に置き換えます。

where句がsargeableであることを確認してください。

実行計画を読むことを学ぶ。

オフィスにパフォーマンスチューニングに関する優れた書籍がいくつかあることを確認してください。

テーブル変数は、一部のインスタンスでは一時テーブルよりも優れており、他のインスタンスでは一時テーブルのパフォーマンスが向上しています。それらを使用する必要がある場合は、両方を試して、特定のケースでどちらがうまく機能するかを確認してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.