SQL クエリのパフォーマンスを向上させるために効果的に適用できる手法は何ですか? 適用される一般的なルールはありますか?
11 に答える
- 主キーを使用する
- 選択を避ける *
- 条件ステートメントを作成するときは、できるだけ具体的にしてください
- 多くの場合、非正規化の方が効率的です
- テーブル変数と一時テーブル (利用可能な場合) は、多くの場合、大きなソース テーブルを使用するよりも優れています。
- 分割ビュー
- インデックスと制約を使用する
内部で実際に何が起こっているかを学びます。次の概念を詳細に理解できるはずです。
- インデックス (インデックスが何であるかだけでなく、実際にどのように機能するか)。
- クラスター化されたインデックスとヒープ割り当てテーブル。
- テキストとバイナリのルックアップ、およびそれらをインライン化できる場合。
- フィルファクター。
- 更新/削除のためにレコードをゴースト化する方法。
- ページ分割が発生する時期とその理由。
- 統計、およびそれらがさまざまなクエリ速度にどのように影響するか。
- クエリプランナー、および特定のデータベースでの動作方法 (たとえば、一部のシステムでは「select *」が遅く、最新の MS-Sql DB ではプランナーが処理できます)。
できる最大のことは、SQL Server クエリ アナライザーでテーブル スキャンを探すことです (「実行計画の表示」をオンにしてください)。それ以外の場合は、MSDN やその他の場所に、適切なアドバイスを提供する無数の記事があります。
余談ですが、クエリを最適化する方法を学び始めたとき、トレースに対して SQL Server クエリ プロファイラーを実行し、生成された SQL を見て、なぜそれが改善されたのかを突き止めようとしました。クエリ プロファイラーは最適とは言えませんが、まずまずのスタートです。
クエリのパフォーマンスを最適化するために確認できることがいくつかあります。
最小限のデータしかないことを確認してください。必要な列のみを選択してください。フィールド サイズを最小限に抑えます。
結合を減らすためにデータベースを非正規化することを検討してください
ループ (つまり、カーソルのフェッチ) を避け、セット操作に固執します。
ストアド プロシージャとしてクエリを実装します。これはプリコンパイルされており、より高速に実行されます。
正しいインデックスが設定されていることを確認してください。データベースが主に検索に使用されている場合は、インデックスを増やすことを検討してください。
実行計画を使用して、処理がどのように行われるかを確認します。回避したいのは、コストがかかるテーブル スキャンです。
自動統計がオンに設定されていることを確認します。SQL は、最適な実行を決定するためにこれを必要とします。詳細については、Mike Gunderloy のすばらしい投稿を参照してください。SQL Server 2005 における統計の基礎
インデックスが断片化されていないことを確認してください。SQL Server インデックスの断片化の削減
- テーブルが断片化されていないことを確認してください。SQL Server 2000 および 2005 でテーブルの断片化を検出する方法
withステートメントを使用して、クエリのフィルタリングを処理します。各サブクエリを可能な限り最小の行数に制限します。次に、サブクエリに参加します。
WITH
master AS
(
SELECT SSN, FIRST_NAME, LAST_NAME
FROM MASTER_SSN
WHERE STATE = 'PA' AND
GENDER = 'M'
),
taxReturns AS
(
SELECT SSN, RETURN_ID, GROSS_PAY
FROM MASTER_RETURNS
WHERE YEAR < 2003 AND
YEAR > 2000
)
SELECT *
FROM master,
taxReturns
WHERE master.ssn = taxReturns.ssn
with ステートメント内のサブクエリは、最終的にインライン ビューまたは自動生成された一時テーブルと同じになる場合があります。私が行っている小売データでは、約 70 ~ 80% の確率でパフォーマンスが向上することがわかりました。
100% の場合、メンテナンスのメリットがあります。
他のいくつかのポイント(私の場合はSQLサーバーに基づいています。各dbバックエンドには独自の実装があるため、すべてのデータベースに当てはまる場合とそうでない場合があります):
ステートメントの選択部分での相関サブクエリは避けてください。それらは本質的にカーソルです。
データを取得するためにテーブルに関数を適用する必要がないように、正しいデータ型を使用するようにテーブルを設計します。たとえば、データを varchar として保存する場合、日付計算を行うのははるかに困難です。
関数を含む結合を頻繁に行っている場合は、テーブルの再設計を検討する必要があります。
WHERE または JOIN 条件に OR ステートメントが含まれている場合 (これは低速です)、UNION ステートメントを使用すると速度が向上する可能性があります。
UNION ALL は、2 つのステートメントが相互に排他的であり、どちらの方法でも同じ結果を返す場合 (およびその場合のみ)、UNION よりも高速です。
NOT EXISTS は通常、NOT IN または ID = null の WHERE 句で左結合を使用するよりも高速です
UPDATE クエリに WHERE 条件を追加して、既に等しい値を更新しないようにします。10,000,000 レコードを更新する場合と 4 レコードを更新する場合の違いは、非常に重要です。
頻繁にクエリを実行したり、大きなレポートを作成したりする場合は、いくつかの値を事前に計算することを検討してください。注文の値の合計は、10,000,000 百万件の注文の結果をレポートに要約するときではなく、注文が作成または調整されたときにのみ実行する必要があります。基になるデータの変更が常に最新の状態になるように、トリガーで事前計算を行う必要があります。また、数値だけである必要はありません。レポートで使用する名前を連結する計算フィールドがあります。
スカラー UDF には注意してください。コードをインラインで配置するよりも遅くなる可能性があります。
一時テーブルは大きなデータ セットの場合は高速になる傾向があり、テーブル変数は小さなデータ セットの場合は高速になります。さらに、一時テーブルにインデックスを付けることができます。
書式設定は通常、SQL よりもユーザー インターフェイスの方が高速です。
実際に必要以上のデータを返さないでください。
これは明らかなように思えますが、信じられないほど頻繁にこれを修正することになります。レコードのフィルター処理に使用していないテーブル、またはステートメントの選択部分で実際にフィールドの 1 つを呼び出していないテーブルに結合しないでください。不要な結合は非常にコストがかかる可能性があります。
他のビューを呼び出す他のビューを呼び出すビューを作成することは、非常に悪い考えです。同じテーブルに 6 回参加する必要があるのに 1 回だけ必要であり、最終結果の 6 つを取得するために基になるビューで 100,000,00 レコードを作成していることに気付く場合があります。
データベースを設計するときは、データを入力するためのユーザー インターフェイスだけでなく、レポートについても考えてください。データは使用されなければ役に立たないので、データベースに格納された後のデータの使用方法と、そのデータの維持または監査方法を検討してください。これにより、デザインが変更されることがよくあります。(これが、ORM にテーブルを設計させるのがよくない考えである理由の 1 つです。ORM は、データの 1 つのユースケースだけを考えています。) ほとんどのデータに影響を与える最も複雑なクエリはレポートにあるため、レポート作成に役立つ変更を設計します。クエリを大幅に高速化 (および簡素化) できます。
データベース固有の機能の実装は、標準の SQL を使用するよりも高速になる可能性があります (これは、彼らが製品を販売する方法の 1 つです)。そのため、データベースの機能を知り、どちらが高速かを調べてください。
そして、あまり頻繁に言うことはできないので、インデックスは多すぎず、少なすぎず、正しく使用してください。そして、WHERE句を検索可能にします(インデックスを使用できます)。
SQL クエリ アナライザーを使用するのが良いスタートになると思います。
Oracleでは、説明計画を見て、クエリのバリエーションを比較できます
テーブルに正しいインデックスがあることを確認してください。データセットを順序付けまたは制限する方法として列を頻繁に使用する場合、インデックスは大きな違いを生む可能性があります。最近の記事で、特にインデックスがない場合、select distinct がクエリを本当に遅くする可能性があることを見ました。
SELECT クエリの明らかな最適化は、結合または WHERE 句で使用される列にインデックスを確保することです。
インデックスを追加するとデータの書き込みが遅くなる可能性があるため、パフォーマンスを監視して DB の書き込みパフォーマンスを損なわないようにする必要がありますが、優れたクエリ分析ツールを使用すると、それに応じてバランスを取ることができます。
- インデックス
- 統計学
- Microsoft スタック上、データベース エンジン チューニング アドバイザー