インデックスを作成するための一般的な規則があるかどうかを知りたいです。このインデックスに含めるフィールドを選択するにはどうすればよいですか、またはそれらを含めない場合はいつですか?
常に環境とデータ量に依存することはわかっていますが、Oracle でインデックスを作成することについて、世界的に受け入れられているルールを作成できるかどうか疑問に思っていました。
インデックスを作成するための一般的な規則があるかどうかを知りたいです。このインデックスに含めるフィールドを選択するにはどうすればよいですか、またはそれらを含めない場合はいつですか?
常に環境とデータ量に依存することはわかっていますが、Oracle でインデックスを作成することについて、世界的に受け入れられているルールを作成できるかどうか疑問に思っていました。
Oracle のドキュメントには、インデックス作成の選択に関する一連の優れた考慮事項があります。
引用:
WHERE 句で頻繁に使用されるキーのインデックス作成を検討してください。
SQL ステートメントでテーブルを結合するために頻繁に使用されるキーのインデックス作成を検討してください。結合の最適化の詳細については、「パフォーマンスのためのハッシュ クラスタの使用」セクションを参照してください。
選択性の高いインデックス キーを選択します。インデックスの選択性は、インデックス付きキーに対して同じ値を持つテーブル内の行の割合です。同じ値を持つ行がほとんどない場合、インデックスの選択性は最適です。注: Oracle は、整合性制約を使用して定義した一意のキーと主キーのキーと式に対して、自動的にインデックスを作成するか、既存のインデックスを使用します。選択性の低い列にインデックスを付けると、データ分布が偏っており、1 つまたは 2 つの値が他の値よりも発生頻度がはるかに低い場合に役立ちます。
個別の値がほとんどないキーまたは式には、標準の B ツリー インデックスを使用しないでください。通常、このようなキーまたは式は選択性が低いため、頻繁に選択されるキー値が他のキー値よりも頻繁に表示されない限り、パフォーマンスは最適化されません。このような場合、同時実行性の高い OLTP アプリケーションのようにインデックスが頻繁に変更されない限り、ビットマップ インデックスを効果的に使用できます。
頻繁に変更される列には索引を付けないでください。インデックス付きの列を変更する UPDATE ステートメントと、インデックス付きのテーブルを変更する INSERT および DELETE ステートメントは、インデックスがない場合よりも時間がかかります。このような SQL ステートメントは、インデックス内のデータとテーブル内のデータを変更する必要があります。また、追加の取り消しとやり直しも生成されます。
関数または演算子を含む WHERE 句にのみ現れるキーにインデックスを付けないでください。MIN または MAX 以外の関数を使用する WHERE 句、またはインデックス付きキーを持つ演算子は、関数ベースのインデックスを除き、インデックスを使用するアクセス パスを使用可能にしません。
多数の同時 INSERT、UPDATE、および DELETE ステートメントが親テーブルと子テーブルにアクセスする場合は、参照整合性制約の外部キーのインデックス作成を検討してください。このようなインデックスを使用すると、子テーブルを共有ロックすることなく、親テーブルで UPDATE および DELETE を実行できます。
キーのインデックスを作成する場合は、クエリのパフォーマンスの向上が、INSERT、UPDATE、および DELETE のパフォーマンスの低下と、インデックスの格納に必要なスペースの使用に見合うかどうかを検討してください。インデックスを使用した場合と使用しない場合の SQL ステートメントの処理時間を比較して、実験することをお勧めします。SQLトレース機能で処理時間を計測できます。
常にインデックスを作成する必要があるものがあります。
その後、クエリをフィルター処理するために頻繁に使用される他の列を探します。典型的な例は人の姓です。
10g Oracle Database Application Developers Guide-Fundamentals、Chapter 5から:
一般に、次のいずれかの状況で列にインデックスを作成する必要があります。
インデックスを作成するタイミングを決定するには、次のガイドラインを使用してください。
一部の列は、インデックス作成の有力な候補です。次の特性の1つ以上を持つ列は、インデックス作成に適しています。
列には多くのnullが含まれていますが、クエリは多くの場合、値を持つすべての行を選択します。この場合、次のようなnull以外のすべての値に一致する比較。
WHERE COL_X> = -9.99 * power(10,125)は、WHERE COL_X ISNOTNULLよりも望ましい
これは、最初にCOL_Xのインデックスを使用するためです(COL_Xが数値列であると想定)。
次の特性を持つ列は、インデックス作成にはあまり適していません。
うわー、それは非常に大きなトピックなので、この形式で答えるのは難しいです. この本を強くお勧めします。
Tapio Lahdenmaki によるリレーショナル データベース インデックスの設計とオプティマイザ
インデックスを使用してテーブルへのアクセスを高速化するだけでなく、テーブルへのアクセスを完全に回避するためにインデックスを作成することもあります。まだ言及されていませんが、重要なことです。
データベースのパフォーマンスを最大限に高めたいのであれば、これには完全な科学があります。
ああ、Oracle に対する特定の最適化の 1 つは、リバース キー インデックスの構築です。シーケンスのように単原子的に増加する値の PK インデックスがあり、同時挿入が多く、その列を範囲スキャンする予定がない場合は、それを逆キー インデックスにします。
これらの最適化がどれほど具体的であるかがわかりますか?
データベースの正規化を調べてください。どのキーが存在する必要があるか、データベースがどのように関連付けられるべきか、およびインデックスに関するヒントについて、多くの優れた業界標準のルールが見つかります。
-アダム
通常、ID 列を前に置き、それらは通常、行を一意に識別します。列の組み合わせでも同じことができます。車を使用した例として... タグまたはナンバー プレートは一意であり、インデックスの資格があります。それら (タグ列) は、主キーの資格を得ることができます。名前で検索する場合は、所有者の名前でインデックスを作成できます。車のメーカーは、あまり変化しないため、最初からインデックスを取得するべきではありません。列のデータがあまり変化しない場合、インデックスは役に立ちません。
SQL を見てみましょう。where 句は何を見ているのでしょうか。それらには索引が必要な場合があります。
測定。問題は何ですか - ページ/クエリに時間がかかりすぎますか? クエリに使用されているもの。それらの列にインデックスを作成します。
警告: インデックスには、更新とスペースのための時間が必要です。
また、完全なテーブル スキャンはインデックスよりも高速な場合があります。小さなテーブルは、インデックスを取得してからテーブルにアクセスするよりも速くスキャンできます。あなたの結合を見てください。