32

インデックスを作成するための一般的な規則があるかどうかを知りたいです。このインデックスに含めるフィールドを選択するにはどうすればよいですか、またはそれらを含めない場合はいつですか?

常に環境とデータ量に依存することはわかっていますが、Oracle でインデックスを作成することについて、世界的に受け入れられているルールを作成できるかどうか疑問に思っていました。

4

6 に答える 6

56

Oracle のドキュメントには、インデックス作成の選択に関する一連の優れた考慮事項があります。

19c の更新: https://docs.oracle.com/en/database/oracle/oracle-database/19/tgdba/designing-and-developing-for-performance.html#GUID-99A7FD1B-CEFD-4E91-9486- 2CBBFC2B7A1D

引用:

  • 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トレース機能で処理時間を計測できます。

于 2008-10-17T19:56:19.657 に答える
10

常にインデックスを作成する必要があるものがあります。

  • 主キー - これらには自動的にインデックスが与えられます (Oracle が使用する適切な既存のインデックスを指定しない場合)
  • 一意のキー - これらには自動的にインデックスが与えられます (同上)
  • 外部キー - これらは自動的にインデックス付けされませんが、制約がチェックされたときのパフォーマンスの問題を回避するために追加する必要があります

その後、クエリをフィルター処理するために頻繁に使用される他の列を探します。典型的な例は人の姓です。

于 2008-10-17T14:10:30.090 に答える
4

10g Oracle Database Application Developers Guide-Fundamentals、Chapter 5から:

一般に、次のいずれかの状況で列にインデックスを作成する必要があります。

  • 列は頻繁に照会されます。
  • 参照整合性制約が列に存在します。
  • 一意のキー整合性制約が列に存在します。

インデックスを作成するタイミングを決定するには、次のガイドラインを使用してください。

  • 大きなテーブルの行の約15%未満を頻繁に取得する場合は、インデックスを作成します。ただし、このしきい値のパーセンテージは、テーブルスキャンの相対速度と、行データがインデックスキーに関してどの程度クラスター化されているかによって大きく異なります。テーブルスキャンが高速であるほど、パーセンテージは低くなります。行データがクラスター化されているほど、パーセンテージは高くなります。
  • 結合のパフォーマンスを向上させるために結合に使用されるインデックス列。
  • 主キーと一意キーには自動的にインデックスがありますが、外部キーにインデックスを作成することもできます。詳細については、第6章「アプリケーション開発におけるデータの整合性の維持」を参照してください。
  • 小さなテーブルにはインデックスは必要ありません。クエリに時間がかかりすぎる場合は、テーブルが小さいものから大きいものに増えている可能性があります。

一部の列は、インデックス作成の有力な候補です。次の特性の1つ以上を持つ列は、インデックス作成に適しています。

  • 値は列内で一意であるか、重複がほとんどありません。
  • さまざまな値があります(通常のインデックスに適しています)。
  • 値の範囲は狭いです(ビットマップインデックスに適しています)。
  • 列には多くのnullが含まれていますが、クエリは多くの場合、値を持つすべての行を選択します。この場合、次のようなnull以外のすべての値に一致する比較。

    WHERE COL_X> = -9.99 * power(10,125)は、WHERE COL_X ISNOTNULLよりも望ましい

    これは、最初にCOL_Xのインデックスを使用するためです(COL_Xが数値列であると想定)。

次の特性を持つ列は、インデックス作成にはあまり適していません。

  • 列には多くのnullがあり、null以外の値を検索しません。
于 2008-10-17T16:40:52.530 に答える
2

うわー、それは非常に大きなトピックなので、この形式で答えるのは難しいです. この本を強くお勧めします。

Tapio Lahdenmaki によるリレーショナル データベース インデックスの設計とオプティマイザ

インデックスを使用してテーブルへのアクセスを高速化するだけでなく、テーブルへのアクセスを完全に回避するためにインデックスを作成することもあります。まだ言及されていませんが、重要なことです。

データベースのパフォーマンスを最大限に高めたいのであれば、これには完全な科学があります。

ああ、Oracle に対する特定の最適化の 1 つは、リバース キー インデックスの構築です。シーケンスのように単原子的に増加する値の PK インデックスがあり、同時挿入が多く、その列を範囲スキャンする予定がない場合は、それを逆キー インデックスにします。

これらの最適化がどれほど具体的であるかがわかりますか?

于 2008-10-17T17:28:47.397 に答える
1

データベースの正規化を調べてください。どのキーが存在する必要があるか、データベースがどのように関連付けられるべきか、およびインデックスに関するヒントについて、多くの優れた業界標準のルールが見つかります。

-アダム

于 2008-10-17T15:07:41.627 に答える
0

通常、ID 列を前に置き、それらは通常、行を一意に識別します。列の組み合わせでも同じことができます。車を使用した例として... タグまたはナンバー プレートは一意であり、インデックスの資格があります。それら (タグ列) は、主キーの資格を得ることができます。名前で検索する場合は、所有者の名前でインデックスを作成できます。車のメーカーは、あまり変化しないため、最初からインデックスを取得するべきではありません。列のデータがあまり変化しない場合、インデックスは役に立ちません。

SQL を見てみましょう。where 句は何を見ているのでしょうか。それらには索引が必要な場合があります。

測定。問題は何ですか - ページ/クエリに時間がかかりすぎますか? クエリに使用されているもの。それらの列にインデックスを作成します。

警告: インデックスには、更新とスペースのための時間が必要です。

また、完全なテーブル スキャンはインデックスよりも高速な場合があります。小さなテーブルは、インデックスを取得してからテーブルにアクセスするよりも速くスキャンできます。あなたの結合を見てください。

于 2008-10-17T14:14:33.467 に答える