最初のRun
query
Sql Server Management Studio
から クエリプランを見て、ボトルネックがどこにあるかを確認します。 「テーブルスキャン」または「インデックススキャン」が表示される場所では、すべてのデータを調べて、探しているものを見つける必要があります。これらの操作に使用できる適切なインデックスを作成すると、パフォーマンスが向上するはずです。
以下に、SQLクエリのパフォーマンスを向上させるためのヒントをいくつか示します。
1つのクエリで複数の結合を避ける
外部結合、相互適用、外部適用、およびその他の複雑なサブクエリを含む複数の結合を使用してSQLクエリを記述しないようにしてください。オプティマイザーが結合順序と結合タイプを決定するための選択肢が減ります。オプティマイザーは、過度に複雑なクロスアプライまたはサブクエリを使用したクエリのパフォーマンスへの影響に関係なく、ネストされたループ結合を使用することを余儀なくされる場合があります。
クエリからカーソルを削除する クエリからカーソルを削除し、セットベースのクエリを使用してみてください。セットベースのクエリは、カーソルベースよりも効率的です。動的カーソルを回避するよりもカーソルを使用する必要がある場合は、クエリオプティマイザで使用できるプランの選択が制限される傾向があります。たとえば、動的カーソルは、オプティマイザをネストされたループ結合の使用に制限します。
相関のないスカラーサブクエリの使用を避ける クエリを書き直して、相関のないスカラーサブクエリをメインクエリの一部ではなく別のクエリとして削除し、出力を変数に格納できます。変数は、メインクエリまたはバッチの後半で参照できます。これにより、オプティマイザーにより良いオプションが提供され、より良い計画とともに正確なカーディナリティ推定値を返すのに役立つ場合があります。
マルチステートメントテーブル値関数(TVF)を避ける マルチステートメントTVFは、インラインTFVよりもコストがかかります。 SQL Serverは、ビューを拡張するのと同じようにインラインTFVをメインクエリに拡張しますが、メインクエリとは別のコンテキストでマルチステートメントTVFを評価し、マルチステートメントの結果を一時的な作業テーブルに具体化します。個別のコンテキストと作業テーブルにより、マルチステートメントTVFのコストが高くなります。
選択性の高いインデックスを作成する 選択性は、テーブル内の修飾行のパーセンテージを定義します(修飾行数/合計行数)。行の総数に対する適格な行数の比率が低い場合、インデックスは非常に選択的であり、最も役立ちます。非クラスター化インデックスは、比率が約5%以下の場合、つまり、インデックスが行の95%を考慮から除外できる場合に最も役立ちます。インデックスがテーブル内の行の5%以上を返している場合、おそらく使用されません。別のインデックスが選択または作成されるか、テーブルがスキャンされます。
インデックスに列を配置する インデックス内の列の順序または位置も、SQLクエリのパフォーマンスを向上させるために重要な役割を果たします。クエリの基準がインデックスキーに最も残っている列と一致する場合、インデックスはSQLクエリのパフォーマンスを向上させるのに役立ちます。ベストプラクティスとして、最も選択的な列は、非クラスター化インデックスのキーの左端に配置する必要があります。
未使用のインデックスを削除する未使用のインデックスを削除すると、データの取得に影響を与えることなく、データの変更を高速化できます。また、実行頻度が低く、特定のインデックスを使用するバッチプロセスの戦略を定義する必要があります。このような場合、バッチプロセスの前にインデックスを作成し、バッチプロセスが完了したときにインデックスを削除すると、データベースのオーバーヘッドを削減できます。
統計の作成と更新 クエリで参照される計算列と複数列の統計の作成と定期的な更新に注意する必要があります。クエリオプティマイザは、テーブル統計の1つ以上の列の値の分布に関する情報を使用して、クエリ結果のカーディナリティまたは行数を推定します。これらのカーディナリティ推定により、クエリオプティマイザは高品質のクエリプランを作成できます。
スキーマ定義を再確認する 最後になりましたが、スキーマ定義を再検討してください。適切なFORIGENKEY、NOT NULL、およびCEHCK制約が設定されているかどうかに注意してください。 FORIGEN KEY制約は、一部の外部結合または半結合を内部結合に変換することで結合を単純化するのに役立ち、CHECK制約は、不要または冗長な述語を削除することで少し役立ちます。