20 索引の管理

索引は、データ・アクセスを高速化できます。索引を作成、変更、監視および削除できます。

20.1 索引について

索引は表およびクラスタと関連付けられているオプション構造で、これにより表に対するSQL問合せをより迅速に実行できます。

このマニュアルで、索引の使用により、索引がない場合よりも高速に情報を検索できるように、Oracle Databaseの索引は、表データへのより高速なアクセス・パスを提供します。索引は問合せをリライトすることなく使用できます。結果は同じですが、より高速に得られます。

Oracle Databaseは、補完的なパフォーマンス機能を持つ複数の索引付け方法を提供します。それらは次のとおりです。

  • Bツリー索引: デフォルトの設定で、最も一般的です。

  • Bツリー・クラスタ索引: 特にクラスタ用に定義します。

  • ハッシュ・クラスタ索引: 特にハッシュ・クラスタ用に定義します。

  • グローバル索引とローカル索引: パーティション表とパーティション索引に関連します。

  • 逆キー索引: Oracle Real Application Clustersアプリケーションに最も役立ちます。

  • ビットマップ索引: サイズが小さいので、小さい値の集合を持つ列に効果的です。

  • ファンクション索引: 事前計算された関数や式の値を含みます。

  • ドメイン索引: アプリケーションまたはカートリッジに固有の索引です。

  • Hierarchical Navigable Small World索引: インメモリー近傍グラフ・ベクトル索引用に作成される索引のデフォルト・タイプです。

  • Inverted File Flatベクトル索引: 近傍パーティション・ベクトル索引用に作成される索引のデフォルト・タイプです。

索引は、対応付けられた表内のデータから論理的にも物理的にも独立しています。索引は独立した構造体であり、記憶域を必要とします。索引は、実表、データベース・アプリケーションまたはその他の索引に影響を与えることなく、作成または削除できます。索引に対応する表に対して行の挿入、更新および削除が発生すると、データベースは索引を自動的にメンテナンスします。索引を削除しても、すべてのアプリケーションは引き続き動作可能です。ただし、それまで索引が付けられていたデータへのアクセスが遅くなります。

関連項目:

20.2 索引を管理するためのガイドライン

ガイドラインに従って索引を管理できます。

関連項目:

20.2.1 表データ挿入後の索引の作成

データは、通常、SQL*Loaderまたはインポート・ユーティリティを使用して表に挿入またはロードされます。データの挿入またはロードの後に表の索引を作成すると効率がよくなります。データのロード前に1つ以上の索引を作成すると、データベースに行が挿入されるたびに索引を更新する必要があります。

すでにデータが格納されている表に索引を作成するには、ソート領域が必要です。索引の作成ユーザーに割り当てられているメモリーから確保されるソート領域もあります。各ユーザーのソート領域の大きさは、初期化パラメータSORT_AREA_SIZEによって決まります。また、データベースでは、索引作成のときにのみユーザーの一時表領域に割り当てられる一時セグメントとの間でソート情報のスワップが行われます。

特定の条件下では、SQL*Loaderのダイレクト・パス・ロードを使用してデータを表にロードし、データがロードされたときに索引が作成されるようにすることも可能です。

関連項目:

SQL*Loaderを使用したダイレクト・パス・ロードの詳細は、『Oracle Databaseユーティリティ』を参照してください。

20.2.2 正しい表および列への索引付け

索引付けに適した表および列についてのガイドラインに従います。

索引を作成するかどうか判断する際は、次のガイドラインを参考にしてください。

  • 大きな表で頻繁に検索される行の割合が15%未満の場合は索引を作成してください。割合は、表スキャンの相対速度、および索引キーに対する行データの分散度によって大きく異なります。表スキャンが高速であるほど割合は低くなり、クラスタ化されている行データが多いほど割合は高くなります。

  • 複数の表を結合するパフォーマンスを改善するには、結合に使用する列に索引を付けます。

    ノート:

    主キーおよび一意キーには自動的に索引が作成されますが、外部キーには必要に応じて索引を作成できます。

  • 問合せに時間がかかりすぎる場合は、表のサイズを確認してください。大幅に変更されている場合、既存の索引(存在する場合)を確認する必要がある場合があります。

索引付けに適した列

列のタイプによっては、索引を付ける方が望ましいものがあります。次のような特性を1つ以上持つ列には、索引の作成を検討してください。

  • 一意の値が比較的多い。

  • 値の範囲が広い(通常の索引が適している)。

  • 値の範囲が狭い(ビットマップ索引が適している)。

  • 列に多くのNULLが含まれているが、通常の問合せでは必ず値を持つ列を選択する。この場合は次の句を使用します。

    WHERE COL_X > -9.99 * power(10,125)
    

    この句は、次の句よりも適しています。

    WHERE COL_X IS NOT NULL
    

    これは、最初の句ではCOL_Xの索引を使用しているためです(COL_Xは数値列とします)。

索引付けに適さない列

次のような特性を持つ列は、索引付けには適していません。

  • 列にNULLが多く含まれていて、NULL以外の値を検索することがない。

LONG列およびLONG RAW列には索引を作成できません。

仮想列

仮想列には、一意索引または非一意索引を作成できます。仮想列に定義された表の索引は、表のファンクション索引と同じです。

20.2.3 パフォーマンスのための索引列の順序付け

CREATE INDEX文の列の順序は、問合せのパフォーマンスに影響を与えます。一般的には、最も頻繁に使用する列を最初に指定します。

たとえば、col1col2およびcol3の各列にアクセスする問合せを高速にするために、列にまたがる単一の索引を作成すると、col1のみにアクセスする問合せ、またはcol1col2にアクセスする問合せが速くなります。しかし、col2のみにアクセスする問合せ、col3のみにアクセスする問合せ、およびcol2col3にアクセスする問合せは速くなりません。

ノート:

先頭列のカーディナリティが非常に低い場合などには、データベースでは、このタイプの索引が使用されることがあります。索引スキップ・スキャンの詳細は、『Oracle Database概要』を参照してください。

20.2.4 表当たりの索引数の制限

表は、多数の索引を持つことができます。ただし、索引の数が多いほど、表を変更するときに発生するオーバーヘッドが増加します。

特に、行を挿入したり削除したりするときは、その表の索引もすべて更新する必要があります。また、列を更新するときには、その列を含む索引もすべて更新する必要があります。

このように、表からデータを検索する速度とその表を更新する速度は二律背反的です。たとえば、表が主に読取り専用である場合、索引を増やすと有効ですが、表が頻繁に更新される場合は、索引を少なくすることをお薦めします。

20.2.5 不必要な索引の削除

必要とされない索引は、削除することをお薦めします。

次のような状況では、索引の削除を検討してください。

  • 問合せを高速化しない。これには、たとえば表が非常に小さい場合や、表の行数は多いものの、索引エントリが非常に少ない場合などがあります。

  • アプリケーションの問合せが索引を使用しない場合。

  • 索引を再作成する前にいったん削除する必要がある場合。

20.2.6 索引およびセグメント作成の遅延

索引セグメントの作成は、対応付けられた表でセグメント作成の遅延が発生すると、遅延されます。これは、索引セグメントの作成には対応付けられた表の動作が反映されるためです。

関連項目:

詳細は、「セグメント作成の遅延の理解」を参照してください

20.2.7 索引サイズの見積りと記憶域パラメータの設定

索引を作成する前にそのサイズを見積っておくと、ディスク領域の計画と管理がいっそう容易になります。

索引の見積りサイズの合計と、表、UNDO表領域およびREDOログ・ファイルの見積りを使用して、作成するデータベースを格納するために必要なディスク容量を決定できます。この見積りを利用して適切なハードウェアを購入できます。

個々の索引の見積りサイズを使用することで、索引が使用するディスク領域をより適切に管理できます。索引を作成するときに、適切な記憶域パラメータを設定し、その索引を使用するアプリケーションのI/Oパフォーマンスを改善できます。たとえば、索引を作成する前に最大サイズを予測したとします。次に索引の作成時に記憶域パラメータを設定すると、表データ・セグメントに対して割り当てられるエクステントが少なくなり、すべての索引データはディスク領域の比較的連続したセクションに格納されます。これにより、この索引に関するディスクのI/O操作にかかる時間が削減されます。

単一の索引エントリの最大サイズは、データベースのブロック・サイズによって異なります。

索引を主キー制約または一意キー制約を規定するために使用する場合、その索引のために作成する索引セグメントの記憶域パラメータは、次のどちらかの方法で設定できます。

  • ENABLE ... CREATE TABLE文またはALTER TABLE文のUSING INDEX

  • ALTER INDEX文のSTORAGE

関連項目:

20.2.8 各索引の表領域の指定

索引はどの表領域にも作成できます。索引は、その索引を付けた表と同じ表領域にも、異なる表領域にも作成できます。

表とその索引に対して同じ表領域を使用すると、(表領域やファイルのバックアップなどの)データベースのメンテナンスやアプリケーションの可用性確保の面で便利です。これは、すべての関連するデータが常にまとまってオンラインになっているためです。

表とその索引に対して(異なるディスク上にある)異なる表領域を使用すると、表と索引を同じ表領域に格納するよりも、パフォーマンスが向上します。これは、ディスクの競合が解消されるためです。表とその索引に対して異なる表領域を使用し、一方の(データまたは索引のいずれかを含む)表領域がオフラインになっている場合には、その表を参照している文が動作する保証はありません。

20.2.9 索引作成のパラレル化

表作成をパラレル化できるのと同様に、索引の作成もパラレル化できます。複数のプロセスが同時に動作して索引を作成するため、1つのサーバー・プロセスが順に索引を作成する場合よりも高速に索引を作成できます。

索引を並行して作成する場合、問合せサーバー・プロセスごとに別々の記憶域パラメータが使用されます。したがって、INITIAL値を5MB、並行度を12で索引を作成する場合は、作成時に60MB以上の記憶域を使用します。

関連項目:

パラレル実行の使用に関する詳細は、『Oracle Database VLDBおよびパーティショニング・ガイド』を参照してください。

20.2.10 索引作成時のNOLOGGINGの使用

CREATE INDEX文でNOLOGGINGを指定すると、索引の作成時に最小限のREDOログ・レコードしか生成されません。

ノート:

NOLOGGINGを使用して作成された索引はアーカイブされないため、索引作成後にバックアップを実行してください。

NOLOGGINGを使用して索引を作成すると、次のような利点があります。

  • REDOログ・ファイルの領域を節約できます。

  • 索引の作成に要する時間が削減できます。

  • 大規模な索引のパラレル作成のパフォーマンスが向上します。

一般に、LOGGINGを指定しないで索引を作成した場合、小規模な索引より大規模な索引の方が相対的にパフォーマンスの向上が大きくなります。小規模な索引をLOGGINGを指定しないで作成しても、索引作成に要する時間にはほとんど影響しません。一方、大規模な索引では、特に索引作成のパラレル化もあわせて指定したときに、パフォーマンスが著しく向上します。

20.2.11 使用禁止または不可視索引の使用について

使用禁止または不可視索引は、バルク・ロードのパフォーマンスを向上させる場合、索引を削除する前に削除によって発生する影響をテストする場合、またはオプティマイザによるその索引の使用を停止する場合に使用します。

使用禁止索引

使用禁止索引は、オプティマイザで無視され、DMLではメンテナンスされません。索引を使用禁止にする理由の1つに、バルク・ロードのパフォーマンス向上があります。(行の挿入時にデータベースで索引のメンテナンスを実行する必要がないため、バルク・ロードが速くなります。)索引を削除した後に再度作成する場合はCREATE INDEX文のパラメータを正確に覚えておく必要がありますが、この方法では索引を使用禁止にした後に再構築できます。

使用禁止状態の索引を作成することも、既存の索引または索引パーティションに使用禁止のマークを付けることもできます。場合によっては、データベースで索引の構築中に障害が発生したときなどに、索引に使用禁止のマークが付けられることがあります。パーティション化された索引のパーティションのうちの1つを使用禁止にした場合、その索引の他のパーティションは有効なままです。

使用禁止の索引または索引パーティションを使用するには、再構築するか、または削除して再作成する必要があります。表を切り捨てると、使用禁止の索引が有効になります。

既存の索引を使用禁止にすると、その索引セグメントが削除されます。

使用禁止の索引の機能は、SKIP_UNUSABLE_INDEXESの初期化パラメータの設定により異なります。SKIP_UNUSABLE_INDEXESTRUE(デフォルト)の場合は、次のようになります。

  • 表に対するDML文は続行されますが、使用禁止索引のメンテナンスは実行されません。

  • 一意制約を規定する使用禁止索引がある場合は、DML文はエラーで終了します。

  • パーティション化されていない索引では、オプティマイザはSELECT文のアクセス計画の作成時に使用禁止索引を考慮しません。唯一の例外は、索引がINDEX()のヒントで明示的に指定された場合です。

  • 1つ以上のパーティションが使用禁止となっているパーティション索引に対しては、オプティマイザでは表の拡張を使用できます。オプティマイザでは、表の拡張を使用して、問合せをUNION ALL文に変換し、ここに、索引付けされたパーティションにアクセスしたり、使用禁止索引を使用してパーティションにアクセスする副問合せを含めます。オプティマイザでは、パーティションで使用できる、最も効率的なアクセス方法を選択できます。表の拡張の詳細は、『Oracle Database SQLチューニング・ガイド』を参照してください。

SKIP_UNUSABLE_INDEXESFALSEの場合は、次のようになります。

  • 使用禁止の索引または索引パーティションがある場合は、これらの索引または索引パーティションを更新するDML文はエラーで終了します。

  • SELECT文は、使用禁止索引または使用禁止索引パーティションが存在しても、オプティマイザでアクセス計画に使用されない場合は、通常どおり実行されます。ただし、オプティマイザが使用禁止索引または使用禁止索引パーティションを使用する場合は、この文はエラーで終了します。

不可視索引

不可視索引を作成したり、既存の索引を不可視にできます。不可視索引は、セッションまたはシステム・レベルでOPTIMIZER_USE_INVISIBLE_INDEXES初期化パラメータを明示的にTRUEに設定しないかぎり、オプティマイザで無視されます。使用禁止索引と異なり、不可視索引はDML文中でも維持されます。パーティション化された索引は不可視にできますが、個別の索引パーティションを不可視にし、残りのパーティションを可視のままにすることはできません。

不可視索引を使用して、次のことを実行できます。

  • 索引を削除する前に、削除した状態をテストできます。

  • アプリケーション全体に影響を与えずに、アプリケーションの特定の操作またはモジュールに対して一時的な索引構造を使用できます。

  • 索引がすでに存在する列セットに索引を追加します。

20.2.12 同じ列セットに対する複数の索引の作成について

同じ列セットに対して、一部が異なる複数の索引を作成できます。たとえば、同じ列セットに対してBツリー索引とビットマップ索引を作成できます。

同じ列のセットに複数の索引がある場合、同時に表示できる索引は1つのみで、他の索引は不可視である必要があります。

同じ列セットに対して異なる索引を作成することは、要求を満たすための柔軟性を実現するのに役立ちます。また、既存の索引を削除して異なる属性を使用して再作成することなく、アプリケーションの移行を実行するために、同じ列セットに対して複数の索引を作成することもできます。

使用例が異なると、役立つ索引のタイプが異なります。たとえば、Bツリー索引は、数多くの同時トランザクションが発生するオンライン・トランザクション処理(OLTP)システムで一般的に使用され、ビットマップ索引は、ほとんど問合せに使用されるデータ・ウェアハウス・システムで一般的に使用されます。同様に、ローカル・パーティション化索引とグローバル・パーティション化索引は、異なる使用例において役立ちます。ローカル・パーティション索引は、パーティションのメンテナンス操作が自動的に適用されるため、管理が容易です。グローバル・パーティション索引は、索引のパーティション化スキームを表のパーティション化スキームと異なるものにする場合に役立ちます。

次のうち、少なくとも1つの索引特性が異なる場合に、同じ列セットに対して複数の索引を作成できます。

  • 索引のタイプが異なります。

    異なるタイプの索引の詳細は、「索引について」および『Oracle Database概要』を参照してください。

    ただし、次の例外があります。

    • 同じ列セットに対して、Bツリー索引とBツリー・クラスタ索引を作成することはできません。

    • 同じ列セットに対して、Bツリー索引と索引構成表を作成することはできません。

  • 索引によって、異なるパーティション化が使用されます。

    パーティション化は、次のように異なることがあります。

    • パーティション化されていない索引と、パーティション化された索引

    • ローカル・パーティション索引と、グローバル・パーティション索引

    • パーティション化タイプ(レンジまたはハッシュ)が異なる索引

  • 索引の一意性プロパティが異なります。

    同じ列セットに対して、一意索引と、非一意索引を作成できます。

20.2.13 索引の結合と再作成に関するコストと利点の検討

不適切な索引サイズの設定やサイズの拡大によって、索引の断片化が生じることがあります。断片化を解消または低減するには、索引を再作成するか、索引を結合します。ただし、どちらの作業を行う場合も、事前に各選択肢のコストと利点を分析し、状況に最も有効な方法を選択してください。

表20-1は、索引を再作成する場合と結合する場合のコストと利点を示しています。

表20-1 索引の結合と再作成に関するコストと利点

索引の再作成 索引の結合

索引を別の表領域に迅速に移動できる。

索引を別の表領域に移動することはできない。

多くのディスク領域を必要とし、コストが高い。

必要なディスク領域が少ないため、コストが低い。

新しいツリーを作成して、可能であればその高さを縮小する。

ツリーの同じブランチ内のリーフ・ブロックを結合する。

オリジナルの索引を削除せずに、記憶域パラメータと表領域パラメータを迅速に変更できる。

索引のリーフ・ブロックを迅速に解放できる。

再利用のために解放できるBツリー索引のリーフ・ブロックがある場合は、次の文を使用してそのようなリーフ・ブロックをマージできます。

ALTER INDEX vmoore COALESCE;

図20-1は、ALTER INDEX COALESCEが索引vmooreに与える影響を示しています。操作を実行する前は、最初の2つのリーフ・ブロックは50%使用されています。したがって、フラグメンテーションを削減して最初のブロック全体を使用しながら、2番目のブロックを解放することが可能になります。

20.2.14 制約を使用禁止または削除する前のコストの検討

一意キーと主キーには対応する索引があるため、UNIQUE制約やPRIMARY KEY制約を使用禁止または削除するかどうかを検討するときには、索引の削除と作成にかかわるコストを考慮に入れてください。

また、UNIQUEキーやPRIMARY KEY制約に対する索引が大きい場合には、その索引を削除して再作成するよりも、その制約を使用可能な状態のままにする方が時間を節約できます。UNIQUE制約やPRIMARY KEY制約を削除または使用禁止にするときには、索引を保持するか削除するかを明示的に指定することもできます。

20.2.15 索引数を減らすためのインメモリー列ストアの使用の検討

インメモリー列ストアは、システム・グローバル領域(SGA)のオプション部分で、高速スキャン用に最適化された表、表パーティション、その他のデータベース・オブジェクトのコピーが格納されます。インメモリー列ストアでは、表データがSGAに行ではなく列ごとに格納されます。

ノート:

この機能は、Oracle Database 12cリリース1 (12.1.0.2)以降で使用可能です。

OLTPまたはデータ・ウェアハウス環境で使用される表には通常、分析およびレポート作成の問合せのパフォーマンスを向上させるために、複数の索引が作成されます。このような索引は、データ操作言語(DML)文のパフォーマンスを低下させる可能性があります。インメモリー列ストアに表を格納すると、問合せのパフォーマンスに影響を及ぼすことなく、分析およびレポート作成の問合せに使用される索引を大幅に削減または消去できます。このような索引を消去すると、トランザクションおよびデータ・ロード操作のパフォーマンスを向上させることができます。

20.3 索引の作成

いくつかの異なるタイプの索引を作成できます。明示的な索引の作成、および制約に関連付けられた索引の作成ができます。

Live SQL:

Oracle Live SQLでの索引の作成に関連する例を参照して実行するには、Oracle Live SQL: 索引の作成にアクセスしてください。

20.3.1 索引作成の前提条件

索引を作成する前に、前提条件を満たす必要があります。

自分のスキーマ内に索引を作成する場合は、次のうち少なくとも1つの前提条件が満たされている必要があります。

  • 索引を付ける表またはクラスタが、自分のスキーマに格納されている。

  • 索引を付ける表に対するINDEX権限を持っている。

  • CREATE ANY INDEXシステム権限を持っている。

別のスキーマ内に索引を作成する場合は、次のすべての前提条件が満たされている必要があります。

  • CREATE ANY INDEXシステム権限を持っている。

  • 目的のスキーマの所有者が、索引または索引パーティションを作成する表領域への割当て制限を持っているか、UNLIMITED TABLESPACEシステム権限を持っている。

20.3.2 索引の明示的な作成

SQL文CREATE INDEXを使用して、索引を明示的に(整合性制約の他に)作成できます。

次の文は、emp表のename列に対してemp_enameという名前の索引を作成します。

CREATE INDEX emp_ename ON emp(ename)
      TABLESPACE users
      STORAGE (INITIAL 20K
      NEXT 20k);

索引に対して、複数の記憶域設定および1つの表領域が明示的に指定されています。索引に記憶域オプション(INITIALNEXTなど)を指定しない場合、デフォルトの表領域または指定された表領域のデフォルトの記憶域オプションが自動的に使用されます。

Live SQL:

Oracle Live SQLの関連する例をOracle Live SQL: 索引の作成で参照して実行してください。

関連項目:

CREATE INDEX文の構文と制限事項については、『Oracle Database SQL言語リファレンス』

20.3.3 一意索引の明示的な作成

索引は、一意にすることも、重複を許可することもできます。一意索引を使用すると、表の複数行のキー列に重複した値が入らないことが保証されます。非一意索引では、列の値にこのような制限はありません。

一意索引を作成するには、CREATE UNIQUE INDEX文を使用します。次の例では、一意索引を作成しています。

CREATE UNIQUE INDEX dept_unique_index ON dept (dname)
      TABLESPACE indx;

別の方法として、目的の列に一意整合性制約を定義することもできます。データベースでは、一意のキーに対して自動的に一意索引を定義することによって、一意整合性制約を規定します。この詳細は次の項に記載されています。ただし、問合せのパフォーマンス向上のために必要な索引は、一意索引も含め、明示的に作成することをお薦めします。

Live SQL:

Oracle Live SQLの関連する例をOracle Live SQL: 索引の作成で参照して実行してください。

関連項目:

パフォーマンス向上のための索引作成の詳細は、『Oracle Database SQLチューニング・ガイド』を参照してください。

20.3.4 制約に対応付けられた索引の作成

SQL文CREATE TABLEまたはALTER TABLEを発行すると、制約に関連付けられた索引を作成できます。

20.3.4.1 制約に対応付けられた索引の作成について

Oracle Databaseは、表にUNIQUEキー整合性制約またはPRIMARY KEY整合性制約を規定するために、一意キーまたは主キーの一意索引を作成します。

この索引は、制約を使用可能にしたときに、データベースによって自動的に作成されます。CREATE TABLE文またはALTER TABLE文を発行して索引を作成する場合は、それ以外に必要なアクションはありませんが、必要に応じて、USING INDEX句を指定して索引作成を制御できます。これは、制約を定義して使用可能にする場合、および定義したが使用禁止にしていた制約を使用可能にする場合のどちらでも可能です。

UNIQUE制約またはPRIMARY KEY制約を使用可能にし、対応する索引を作成するには、表の所有者が索引を格納する表領域の割当て制限またはUNLIMITED TABLESPACEシステム権限を持っている必要があります。特に指定しないかぎり、制約に対応付けられた索引には、常に制約と同じ名前が付けられます。

ノート:

並列性を利用できるように制約を使用可能にする効率的な手順は、「整合性制約の効率的な使用: 手順」を参照してください。

20.3.4.2 制約に対応付けられた索引に対する記憶域オプションの指定

USING INDEX句を使用すると、 UNIQUE制約またはPRIMARY KEY制約に対応する索引の記憶域オプションを設定できます。

次のCREATE TABLE文は、主キー制約を使用可能にして、対応する索引の記憶域オプションを指定します。

CREATE TABLE emp (
     empno NUMBER(5) PRIMARY KEY, age INTEGER)
     ENABLE PRIMARY KEY USING INDEX
     TABLESPACE users;
20.3.4.3 制約に対応付けられた索引の指定

制約に対応付けられた索引の詳細を指定できます。

UNIQUE制約およびPRIMARY KEY制約に対応付けられた索引をより明示的に制御する場合、データベースでは次のことが可能です。

  • 制約を規定するために使用する既存の索引の指定

  • 索引の作成と制約の規定に使用するCREATE INDEX文の指定

これらのオプションは、USING INDEX句を使用して指定します。次にいくつかの例を示します。

例1:

CREATE TABLE a (
     a1 INT PRIMARY KEY USING INDEX (create index ai on a (a1)));

Live SQL:

Oracle Live SQLの関連する例をOracle Live SQL: 索引の作成で参照して実行してください。

例2:

CREATE TABLE b(
     b1 INT, 
     b2 INT, 
     CONSTRAINT bu1 UNIQUE (b1, b2) 
                    USING INDEX (create unique index bi on b(b1, b2)),
     CONSTRAINT bu2 UNIQUE (b2, b1) USING INDEX bi);

例3:

CREATE TABLE c(c1 INT, c2 INT);
CREATE INDEX ci ON c (c1, c2);
ALTER TABLE c ADD CONSTRAINT cpk PRIMARY KEY (c1) USING INDEX ci;

単一の文で制約とともに索引を作成し、同じ文でその索引を別の制約にも使用する場合、Oracleでは、索引を再使用する前に索引を作成するための句の再編成を試みます。

20.3.5 大きな索引の作成

非常に大きな索引を作成する場合は、索引の作成のために大きな一時表領域の割当てを検討してください。

これを行うには、次のステップを完了します。

  1. CREATE TABLESPACE文またはCREATE TEMPORARY TABLESPACE文を使用して、新しい一時表領域を作成します。
  2. これを自分の新しい一時表領域にするには、ALTER USER文のTEMPORARY TABLESPACEオプションを使用します。
  3. CREATE INDEX文を使用して、索引を作成します。
  4. DROP TABLESPACE文を使用して、この表領域を削除します。次にALTER USER文を使用して、自分の一時表領域を元の一時表領域に再設定します。

この手順により、通常使用している一時表領域(ほとんどの場合、共有されている)が極度に肥大化して今後のパフォーマンスに影響を及ぼす問題を回避できます。

20.3.6 オンラインでの索引の作成

索引をオンラインで作成および再作成できます。そのため、実表の索引を作成または再作成する際に、同時に実表も更新できます。

索引の作成中にDML操作を実行できますが、DDL操作はできません。索引をオンラインで作成または再作成するとき、パラレルDMLはサポートされません。

次の文は、オンラインでの索引作成操作を示しています。

CREATE INDEX emp_name ON emp (mgr, emp1, emp2, emp3) ONLINE;

ノート:

オンライン索引ビルドが完了するまでの時間は、表のサイズおよび同時に実行しているDML文の数に比例することに注意してください。したがって、オンライン索引ビルドはDMLアクティビティが低いときに開始することをお薦めします。

Live SQL:

Oracle Live SQLの関連する例をOracle Live SQL: 索引の作成で参照して実行してください。

20.3.7 ファンクション索引の作成

ファンクション索引を使用すると、関数や式から返される値を修飾する問合せが可能です。関数や式の値は、事前に計算されて索引に格納されます。

ユーザー定義のファンクションに基づく索引の場合は、従来型の索引を作成するための前提条件に加えて、これらのファンクションにDETERMINISTICのマークが設定されている必要があります。また、ファンクションに基づく索引はファンクションの所有者の資格証明を使用して実行されるため、ファンクションに対するEXECUTEオブジェクト権限がある必要があります。

ノート:

CREATE INDEXでは、ファンクション索引で最後に使用された関数のタイムスタンプが格納されます。このタイムスタンプは、索引の妥当性チェック時に更新されます。ファンクション索引について表領域のPoint-in-Timeリカバリを実行する場合、索引で最後に使用された関数のタイムスタンプが索引に格納されたタイムスタンプより新しい場合は、その索引には無効を示すマークが設定されます。ANALYZE INDEX...VALIDATE STRUCTURE文を使用して、この索引の妥当性をチェックする必要があります。

ファンクション索引の具体例として、ファンクションarea(geo)に定義されているファンクション索引(area_index)を定義する次の文を示します。

CREATE INDEX area_index ON rivers (area(geo));

次のSQL文では、area(geo)WHERE句で参照されているため、オプティマイザは索引area_indexの使用を考慮します。

SELECT id, geo, area(geo), desc
     FROM rivers     
     WHERE Area(geo) >5000;

ファンクション索引は使用するファンクションに依存するため、ファンクションの変更時に無効にできます。ファンクションが有効な場合は、ALTER INDEX...ENABLE文を使用して、使用禁止になっているファンクション索引を使用可能にすることができます。ALTER INDEX...DISABLE文では、ファンクション索引を使用禁止にすることができます。ファンクションの本体で作業をする場合は、ファンクション索引を使用禁止にするか検討してください。

ノート:

ファンクション索引を作成するかわりに、仮想列をターゲット表に追加して仮想列に索引を付けることができます。詳細は、「表について」を参照してください。

関連項目:

20.3.8 圧縮索引の作成

データベースが大きくなったら、ディスク領域を節約するために、索引圧縮の使用を検討してください。

20.3.8.1 接頭辞圧縮を使用した索引の作成

接頭辞圧縮(キー圧縮とも呼ばれます)を使用して索引を作成すると、キー列の接頭辞が同じ値で繰り返し格納されることが回避されます。接頭辞圧縮は、先頭列で数多くの重複が発生する非一意索引に対して最も有効です。

接頭辞圧縮によって、索引キーは接頭辞および接尾辞エントリに分割されます。圧縮するために、接頭辞エントリは索引ブロック内のすべての接尾辞エントリ間で共有されます。このような共有によって、領域が大幅に節約され、各索引ブロックに格納できるキー数が増え、パフォーマンスが向上します。

接頭辞圧縮は、次のような状況で役立ちます。

  • ROWIDを追加してキーを一意にしている非一意索引がある場合。このような状況で接頭辞圧縮を使用すると、重複キーは接頭辞エントリとして索引ブロックにROWIDなしで格納されます。残りの行は、ROWIDのみからなる接尾辞エントリとなります。

  • 一意の複数列索引がある場合。

接頭辞圧縮を使用可能にするには、COMPRESS句を使用します。また、接頭辞の長さをキー列の数で指定して、キー列が接頭辞および接尾辞エントリにどのように分割されるかを識別できます。たとえば、次の文は、索引リーフ・ブロックの重複するキーを圧縮します。

CREATE INDEX  hr.emp_ename ON emp(ename)
   TABLESPACE users
   COMPRESS 1;

また、再作成中に、COMPRESS句を指定することもできます。たとえば、次のようにして、再作成中に圧縮を使用禁止にすることができます。

ALTER INDEX hr.emp_ename REBUILD NOCOMPRESS;

ALL_INDEXESビューおよびALL_PART_INDEXESビューのCOMPRESSION列には、索引が圧縮されるかどうかが表示され、圧縮される場合は索引で使用可能な圧縮のタイプが表示されます。

Live SQL:

Oracle Live SQLの関連する例をOracle Live SQL: 索引の作成で参照して実行してください。

関連項目:

20.3.8.2 拡張索引圧縮を使用した索引の作成

拡張索引圧縮は、接頭辞圧縮の適切な候補ではない索引を含むすべてのサポートされている索引で正常に動作します。拡張索引圧縮を使用して索引を作成すると、索引への効率的なアクセスを提供しつつ、すべての一意の索引および一意ではない索引のサイズが減少し、圧縮率が著しく向上します。

パーティション索引の場合は、パーティションごとにパーティションの圧縮タイプを指定できます。親索引が圧縮されていない場合でも、索引パーティションに対して拡張索引圧縮を指定できます。

拡張索引圧縮は、ブロック・レベルに作用し、各ブロックを最適に圧縮できます。

拡張索引圧縮を有効にするにはCOMPRESS ADVANCED句を使用し、次の圧縮レベルを指定できます。

  • LOW: このレベルは、最小のCPUオーバーヘッドで低い圧縮率を提供します。COMPRESS ADVANCED LOWを有効化する前に、データベースの互換性レベルが12.1.0以上である必要があります。

  • HIGH: このレベル(デフォルト)では、わずかなCPUオーバーヘッドでより高い圧縮率が提供されます。COMPRESS ADVANCED HIGHを有効化する前に、データベースの互換性レベルが12.2.0以上である必要があります。

    CREATE INDEX DDL文を実行すると、ブロックは行で満たされます。高圧縮レベルでブロックが一杯になると、次の行を挿入するための十分な領域が確保される場合、ブロックは拡張索引圧縮を使用して圧縮されます。ブロックが一杯なると、受信キーの挿入のための十分な領域が確保される場合、ブロックは拡張索引圧縮を使用して再圧縮され分割を回避します。

ALL_INDEXESビューのCOMPRESSION列には、索引が圧縮されるかどうかが表示され、圧縮される場合は索引で使用可能な圧縮のタイプが表示されます。COMPRESSION列に指定できる値は、ADVANCED HIGHADVANCED LOWDISABLEDまたはENABLEDです。ALL_IND_PARTITIONSビューおよびALL_IND_SUBPARTITIONSビューのCOMPRESSION列は、パーティションまたはサブパーティションで索引圧縮がENABLEDまたはDISABLEDのいずれであるかを示します。

ノート:

  • 拡張索引圧縮は、ビットマップ索引または索引構成表ではサポートされていません。

  • 低レベルの拡張索引圧縮を有効にした場合は、単一列の一意の索引に拡張索引圧縮を指定できません。高レベルの拡張索引圧縮が有効にされている場合、この制限は適用されません。

例20-1 索引の作成時における低レベルの高度な索引圧縮の有効化

たとえば、次の文を実行すると、hr.emp_mndp_ix索引の作成時に低レベルの拡張索引圧縮が使用可能になります。

CREATE INDEX hr.emp_mndp_ix ON hr.employees(manager_id, department_id)
   COMPRESS ADVANCED LOW;

例20-2 索引の再作成時における高レベルの高度な索引圧縮の有効化

また、索引の再作成中に、COMPRESS ADVANCED句を指定することもできます。たとえば、次のようにして、再作成中にhr.emp_manager_ix索引に対して高レベルの拡張索引圧縮を使用可能にできます。

ALTER INDEX hr.emp_manager_ix REBUILD COMPRESS ADVANCED HIGH;

20.3.9 使用禁止索引の作成

UNUSABLE状態の索引を作成した場合、オプティマイザで無視され、DMLではメンテナンスされません。使用禁止の索引を使用可能にする場合、再構築するか、または削除して再作成する必要があります。

索引がパーティション化されている場合、索引パーティションはすべてUNUSABLEとしてマークされます。

データベースは使用禁止索引の作成時に索引セグメントを作成しません。

次の手順では、使用禁止の索引を作成する方法と、データベースに索引に関する詳細を問い合せる方法を示します。

使用禁止索引を作成するには:

  1. 必要に応じて、索引を付ける表を作成します。

    たとえば、次のように、hr.employees_partという名前でハッシュ・パーティション表を作成します。

    sh@PROD> CONNECT hr
    Enter password: **
    Connected.
    
    hr@PROD> CREATE TABLE employees_part
      2    PARTITION BY HASH (employee_id) PARTITIONS 2
      3    AS SELECT * FROM employees;
     
    Table created.
    
    hr@PROD> SELECT COUNT(*) FROM employees_part;
     
      COUNT(*)
    ----------
           107
    
  2. キーワードUNUSABLEで索引を作成します。

    次の例では、employees_partにローカル・パーティション索引を作成し、索引パーティションにp1_i_emp_enameおよびp2_i_emp_enameという名前を付け、p1_i_emp_enameを使用禁止にしています。

    hr@PROD> CREATE INDEX i_emp_ename ON employees_part (employee_id)
      2    LOCAL (PARTITION p1_i_emp_ename UNUSABLE, PARTITION p2_i_emp_ename);
     
    Index created.
    
  3. (オプション)データ・ディクショナリに問い合せて索引が使用禁止になっていることを確認できます。

    次の例では、索引i_emp_enameとその2つのパーティションのステータスを問い合せて、パーティションp2_i_emp_enameのみが使用禁止になっていることを示しています。

    hr@PROD> SELECT INDEX_NAME AS "INDEX OR PARTITION NAME", STATUS
      2  FROM   USER_INDEXES
      3  WHERE  INDEX_NAME = 'I_EMP_ENAME'
      4  UNION ALL
      5  SELECT PARTITION_NAME AS "INDEX OR PARTITION NAME", STATUS
      6  FROM   USER_IND_PARTITIONS
      7  WHERE  PARTITION_NAME LIKE '%I_EMP_ENAME%';
     
    INDEX OR PARTITION NAME        STATUS
    ------------------------------ --------
    I_EMP_ENAME                    N/A
    P1_I_EMP_ENAME                 UNUSABLE
    P2_I_EMP_ENAME                 USABLE
    
  4. (オプション)データ・ディクショナリに問い合せて、パーティションの記憶域が存在するかどうかを確認できます。

    たとえば、次の問合せは索引パーティションp2_i_emp_enameのみがセグメントを占有していることを示しています。p1_i_emp_enameは使用禁止として作成したため、セグメントが割り当てられませんでした。

    hr@PROD> COL PARTITION_NAME FORMAT a14
    hr@PROD> COL SEG_CREATED FORMAT a11
    hr@PROD> SELECT p.PARTITION_NAME, p.STATUS AS "PART_STATUS",
      2         p.SEGMENT_CREATED AS "SEG_CREATED",   
      3  FROM   USER_IND_PARTITIONS p, USER_SEGMENTS s
      4  WHERE  s.SEGMENT_NAME = 'I_EMP_ENAME';
     
    PARTITION_NAME PART_STA SEG_CREATED 
    -------------- -------- ----------- 
    P2_I_EMP_ENAME USABLE   YES       
    P1_I_EMP_ENAME UNUSABLE NO

関連項目:

20.3.10 不可視索引の作成

不可視索引とは、セッションまたはシステム・レベルでOPTIMIZER_USE_INVISIBLE_INDEXES初期化パラメータを明示的にTRUEに設定しないかぎり、オプティマイザで無視される索引です。

不可視索引を作成するには:

  • CREATE INDEX文をINVISIBLEキーワードとともに指定します。

    次の文は、emp表のename列に対してemp_enameという名前の不可視索引を作成します。

    CREATE INDEX emp_ename ON emp(ename)
          TABLESPACE users
          STORAGE (INITIAL 20K
          NEXT 20k)
          INVISIBLE;
    

20.3.11 同じ列セットに対する複数の索引の作成

同じ列セットに対して、一部が異なる複数の索引を作成できます。

同じ列セットに対して複数の索引を作成する場合は、次の前提条件が満たされている必要があります。

  • 「索引の作成」に示されている、必要な権限の前提。

  • 同じ列セットに対する索引のうち、任意の時点で可視にできるのは1つのみとなります。

    可視の索引を作成する場合、その列セットに対するすべての既存の索引が不可視である必要があります。

    かわりに、列セットに対して不可視索引を作成できます。

たとえば、次のステップを実行すると、oe.orders表の同じ列セットに対して、Bツリー索引とビットマップ索引が作成されます。

  1. oe.orders表のcustomer_id列とsales_rep_id列に対して、Bツリー索引を作成します。
    CREATE INDEX oe.ord_customer_ix1 ON oe.orders (customer_id, sales_rep_id);
    

    oe.ord_customer_ix1索引はデフォルトで可視となります。

  2. ステップ1で作成した索引を変更して、不可視にします。
    ALTER INDEX oe.ord_customer_ix1 INVISIBLE;
    

    かわりに、ステップ1でINVISIBLE句を追加すると、このステップを省略できます。

  3. oe.orders表のcustomer_id列とsales_rep_id列に対して、ビットマップ索引を作成します。
    CREATE BITMAP INDEX oe.ord_customer_ix2 ON oe.orders (customer_id, sales_rep_id);
    

    oe.ord_customer_ix2索引はデフォルトで可視となります。

    ステップ1で作成したoe.ord_customer_ix1索引が可視である場合、このステップのCREATE BITMAP INDEX文ではエラーが返されます。

20.3.12 ベクトル索引の作成

ベクトル索引を作成してベクトル検索を高速化できます。

ベクトル索引を作成するには、Oracle Database AI Vector Searchユーザーズ・ガイドを参照してください。

20.4 索引の変更

索引は、記憶域の特性の変更、再作成、使用不能化、表示/非表示にするなどのタスクを完了することで変更できます。

20.4.1 索引の変更について

索引を変更するには、その索引が自分のスキーマに含まれているか、またはALTER ANY INDEXシステム権限を持っている必要があります。

ALTER INDEX文では、次の操作を実行できます。

  • 既存の索引の再作成または結合

  • 未使用領域の割当て解除または新規エクステントの割当て

  • パラレル実行の指定(または指定解除)およびその並列度の変更

  • 記憶域パラメータまたは物理属性の変更

  • LOGGINGまたはNOLOGGINGの指定

  • 接頭辞圧縮の使用可能または使用禁止の設定

  • 拡張圧縮を有効化または無効化します

  • 索引へのUNUSABLEマークの設定

  • 索引の不可視化

  • 索引の名前変更

  • 索引使用状況の監視の開始または停止

索引の列構造は変更できません。

関連項目:

20.4.2 索引の記憶域特性の変更

主キーと一意キーの整合性制約を規定するためにデータベースによって作成される索引も含めて、どの索引の記憶域パラメータも、ALTER INDEX文を使用して変更できます。

たとえば、次の文はemp_ename索引を変更します。

ALTER INDEX emp_ename
     STORAGE (NEXT 40);

パラメータINITIALMINEXTENTSは変更できません。他の記憶域パラメータの新しい設定はすべて、その後に索引に割り当てられるエクステントにのみ影響します。

整合性制約を実装する索引では、ENABLE句のUSING INDEX副次句を指定したALTER TABLE文を発行することによって、記憶域パラメータを調整できます。たとえば、次の文は、表empに作成された索引の記憶域オプションを変更して、主キー制約を規定します。

ALTER TABLE emp
     ENABLE PRIMARY KEY USING INDEX;

関連項目:

ALTER INDEX文の構文と制限事項については、『Oracle Database SQL言語リファレンス』

20.4.3 既存の索引の再作成

索引を再作成するときは、既存の索引をデータソースとして使用できます。このようにして索引を作成すると、記憶特性の変更や新しい表領域への移動ができます。既存のデータソースに基づいて索引を再作成すると、ブロック内の断片化も解消されます。

索引を削除してからCREATE INDEX文を使用するよりも、既存の索引を再構築する方がパフォーマンスに優れています。既存の索引を再作成する前に、「索引の結合と再作成に関するコストと利点の検討」の説明に従って、索引を再作成する方法と結合する方法のコストと利点を比較してください。

次の文は、既存の索引emp_nameを再作成します。

ALTER INDEX emp_name REBUILD;

REBUILD句は索引名の直後に使用し、他のオプションの前に置く必要があります。DEALLOCATE UNUSED句とともに使用することはできません。

索引はオンラインで再作成できます。オンラインで再作成することにより、再作成と同時に実表を更新できます。次の文は、emp_name索引をオンラインで再作成します。

ALTER INDEX emp_name REBUILD ONLINE;

別のユーザーのスキーマにオンラインで索引を再作成するには、ALTER ANY INDEXシステム権限が必要です。

ノート:

オンラインでの索引の再作成には、別の方式による索引の再作成に比べ、処理できるキーの最大長に関して、より厳しい制限があります。オンラインでの再作成時にORA-01450(キーの最大長超過)エラーが発生した場合は、オフラインで再作成し結合を試みるか、索引を削除し再作成します。

索引の再作成に必要な大きさの領域がない場合、かわりに索引を結合する方法が使用できます。索引の結合はオンライン操作です。

20.4.4 索引の使用禁止化

索引を使用禁止にした場合、オプティマイザで無視され、DMLではメンテナンスされません。パーティション化された索引のパーティションのうちの1つを使用禁止にした場合、その索引の他のパーティションは有効なままです。

使用禁止の索引または索引パーティションを使用する場合は、事前に索引または索引パーティションを再作成するか、または削除した後再作成する必要があります。

次の手順では、索引および索引パーティションを使用禁止にする方法と、オブジェクトのステータスを問い合せる方法を示します。

索引を使用禁止にするには:

  1. データ・ディクショナリに問い合せて、既存の索引または索引パーティションが使用可能であるか、使用禁止であるかを確認します。

    たとえば、次の問合せを発行します(スペースの節約のため出力を切り捨てています)。

    hr@PROD> SELECT INDEX_NAME AS "INDEX OR PART NAME", STATUS, SEGMENT_CREATED
      2  FROM   USER_INDEXES
      3  UNION ALL
      4  SELECT PARTITION_NAME AS "INDEX OR PART NAME", STATUS, SEGMENT_CREATED
      5  FROM   USER_IND_PARTITIONS;
     
    INDEX OR PART NAME             STATUS   SEG
    ------------------------------ -------- ---
    I_EMP_ENAME                    N/A      N/A
    JHIST_EMP_ID_ST_DATE_PK        VALID    YES
    JHIST_JOB_IX                   VALID    YES
    JHIST_EMPLOYEE_IX              VALID    YES
    JHIST_DEPARTMENT_IX            VALID    YES
    EMP_EMAIL_UK                   VALID    NO
    .
    .
    .
    COUNTRY_C_ID_PK                VALID    YES
    REG_ID_PK                      VALID    YES
    P2_I_EMP_ENAME                 USABLE   YES
    P1_I_EMP_ENAME                 UNUSABLE NO
     
    22 rows selected.
    

    前述の出力は、索引パーティションp1_i_emp_enameのみが使用禁止であることを示しています。

  2. 索引または索引パーティションを使用禁止にするには、UNUSABLEキーワードを指定します。

    次の例では、索引emp_email_ukを使用禁止にしています。

    hr@PROD> ALTER INDEX emp_email_uk UNUSABLE;
     
    Index altered.
    

    次の例では、索引パーティションp2_i_emp_enameを使用禁止にしています。

    hr@PROD> ALTER INDEX i_emp_ename MODIFY PARTITION p2_i_emp_ename UNUSABLE;
     
    Index altered.
    
  3. (オプション)データ・ディクショナリに問い合せて、ステータス変更を確認できます。

    たとえば、次の問合せを発行します(スペースの節約のため出力を切り捨てています)。

    hr@PROD> SELECT INDEX_NAME AS "INDEX OR PARTITION NAME", STATUS, 
      2  SEGMENT_CREATED
      3  FROM   USER_INDEXES
      4  UNION ALL
      5  SELECT PARTITION_NAME AS "INDEX OR PARTITION NAME", STATUS, 
      6  SEGMENT_CREATED
      7  FROM   USER_IND_PARTITIONS;
     
    INDEX OR PARTITION NAME        STATUS   SEG
    ------------------------------ -------- ---
    I_EMP_ENAME                    N/A      N/A
    JHIST_EMP_ID_ST_DATE_PK        VALID    YES
    JHIST_JOB_IX                   VALID    YES
    JHIST_EMPLOYEE_IX              VALID    YES
    JHIST_DEPARTMENT_IX            VALID    YES
    EMP_EMAIL_UK                   UNUSABLE NO
    .
    .
    .
    COUNTRY_C_ID_PK                VALID    YES
    REG_ID_PK                      VALID    YES
    P2_I_EMP_ENAME                 UNUSABLE NO
    P1_I_EMP_ENAME                 UNUSABLE NO
     
    22 rows selected.
    

    i_emp_enameセグメントとemp_email_ukセグメントが消費している領域を問い合せると、どちらのセグメントも存在しなくなったことが示されます。

    hr@PROD> SELECT SEGMENT_NAME, BYTES
      2  FROM   USER_SEGMENTS
      3  WHERE  SEGMENT_NAME IN ('I_EMP_ENAME', 'EMP_EMAIL_UK');
     
    no rows selected

関連項目:

20.4.5 索引の不可視化または可視化

索引を非表示にするのは、使用禁止または削除の代替手段です。

不可視索引は、セッションまたはシステム・レベルでOPTIMIZER_USE_INVISIBLE_INDEXES初期化パラメータを明示的にTRUEに設定しないかぎり、オプティマイザで無視されます。個別の索引パーティションは不可視にできません。試みた場合はエラーとなります。

索引を不可視にするには:

  • 次のSQL文を発行します。

    ALTER INDEX index INVISIBLE;
    

不可視状態の索引を可視にするには:

  • 次のSQL文を発行します。

    ALTER INDEX index VISIBLE;
    

ノート:

同じ列セットに対して複数の索引がある場合、これらの索引のうち、任意の時点で可視にできるのは1つのみとなります。列セットに対する索引を可視にしようとしたとき、同じ列セットに対する別の索引が可視であると、エラーが返されます。

索引が可視か不可視かを判別するには:

  • USER_INDEXESALL_INDEXESまたはDBA_INDEXESディクショナリ・ビューの問合せを行います。

    たとえば、索引ind1が不可視かどうかを判別するには、次の問合せを発行します。

    SELECT INDEX_NAME, VISIBILITY FROM USER_INDEXES
       WHERE INDEX_NAME = 'IND1';
    
    INDEX_NAME   VISIBILITY
    ----------   ----------
    IND1         VISIBLE

20.4.6 索引の名前変更

RENAME句を含むALTER INDEX文を使用して、索引の名前を変更できます。

索引の名前を変更するには、次の文を発行します。

ALTER INDEX index_name RENAME TO new_name;

20.4.7 索引の使用状況の監視

Oracle Databaseでは、自動的に索引が監視されて、それらが使用中かどうかが判別されます。未使用の索引がある場合は、それを削除して不要な文によるオーバーヘッドを解消できます。

索引について、それがアクセスされているかどうかを確認するには、ビューDBA_INDEX_USAGEを問い合せます。このビューにはTOTAL_ACCESS_COUNT列があり、その値は、監視期間内に索引が使用されると増分されます。このビューには、最後に索引が使用された時間も含まれます。DBA_INDEX_USAGEでは、索引ごとの累積統計が示されます。
SQL> SELECT object_id, name, owner, total_access_count, total_exec_count, last_used
     FROM   dba_index_usage
     WHERE  name = 'OBJECT_ID_IDX';

 OBJECT_ID NAME             OWNER        TOTAL_ACCESS_COUNT TOTAL_EXEC_COUNT LAST_USED
---------- ---------------- ------------ ------------------ ---------------- --------------------
    107585 OBJECT_ID_IDX    C##TESTID                     1                1 08-Mar-2024 04:34:29
ビューV$INDEX_USAGE_INFOでは、最後のフラッシュ(15分ごとに発生する)以降の索引使用状況が記録されます。
SQL> SELECT index_stats_enabled, index_stats_collection_type, active_elem_count, last_flush_time
     FROM   v$index_usage_info;

INDEX_STATS_ENABLED INDEX_STATS_COLLECTION_TYPE ACTIVE_ELEM_COUNT LAST_FLUSH_TIME
------------------- --------------------------- ----------------- ---------------------------
                  1                           0                 0 08-MAR-24 05.04.33.564 AM

20.5 索引の領域使用の監視

索引のキー値が頻繁に挿入、更新および削除されると、時間が経つにつれて領域の効率性が失われることがあります。

索引の領域の使用状況の効率性を定期的に監視するには、まずANALYZE INDEX...VALIDATE STRUCTURE文を使用し、次にINDEX_STATSビューを問い合せて索引構造を分析します。

SELECT PCT_USED FROM INDEX_STATS WHERE NAME = 'index';

索引の領域使用の割合は、どれくらい頻繁に索引キーが挿入、更新または削除されるかによって変化します。次の一連の操作を何度か実行し、索引の平均的な領域使用効率の履歴を作成してください。

  • 統計分析

  • 索引の検証

  • PCT_USEDのチェック

  • 索引の削除および再作成(または結合)

索引の領域使用がその平均を下回っているときは、索引を削除してから再作成または結合することによって、索引の領域を圧縮できます。

20.6 索引の削除

索引は、DROP INDEX文により削除できます。

索引を削除するには、その索引が自分のスキーマに含まれているか、またはDROP ANY INDEXシステム権限を持っている必要があります。

索引を削除するのは、次のような場合です。

  • 索引が不要になった場合。

  • 対応する表に対して発行した問合せで、索引が予想されたパフォーマンスの改善を達成していない場合。たとえば、表が非常に小さい、または表には多くの行があるものの、索引エントリが非常に少ないなどがこれに該当します。

  • アプリケーションに索引を使用するデータ問合せが含まれない場合。

  • 索引が無効になり、再作成する前に削除する必要がある場合。

  • 索引がかなり断片化し、再作成する前に削除する必要がある場合。

索引が削除されると、その索引のセグメントのエクステントはすべて、索引を含んでいる表領域に戻され、表領域内の他のオブジェクトで利用できます。

索引を削除する方法は、索引の作成方法、つまりCREATE INDEX文によって索引を明示的に作成したか、または表にキー制約を定義することによって索引を暗黙的に作成したかによって異なります。CREATE INDEX文を使用して明示的に作成した索引は、DROP INDEX文で削除できます。次の文は、emp_ename索引を削除します。

DROP INDEX emp_ename;

使用可能になっているUNIQUEキー制約やPRIMARY KEY制約に対応付けられた索引のみを削除することはできません。制約に対応付けられた索引を削除するには、制約自体を使用禁止にするかまたは削除します。

ノート:

表を削除すると、対応する索引はすべて自動的に削除されます。

関連項目:

20.7 自動索引の管理

自動索引作成機能を使用することで、Oracleデータベースで自動索引を構成して使用し、データベースのパフォーマンスを向上させることができます。

20.7.1 自動索引作成について

自動索引作成機能では、Oracleデータベース内の索引管理タスクが自動化されます。自動索引作成では、アプリケーション・ワークロードの変化に基づいてデータベース内の索引が自動的に作成および削除されるため、データベース・パフォーマンスが向上します。自動的に管理される索引は、自動索引と呼ばれます。

索引構造は、データベース・パフォーマンスにとって重要な機能です。OLTPアプリケーションでは、索引は非常に重要です。これらのアプリケーションでは、大規模なデータ・セットが使用され、1日に何百万ものSQL文が実行されます。データ・ウェアハウス・アプリケーションでも、索引は非常に重要です。これらのアプリケーションでは、通常は、非常に大きな表から比較的少量のデータを問い合せます。アプリケーション・ワークロードに変化があったときに索引を更新しないと、既存の索引が原因で、データベースのパフォーマンスが大幅に低下する可能性があります。

自動索引作成では、アプリケーション・ワークロードの変化に基づいてOracleデータベース内で索引を自動的かつ動的に管理することで、データベースのパフォーマンスが向上します。

自動索引作成では、次の機能が提供されます。

  • バックグラウンドで、事前定義された時間間隔で定期的に自動索引作成プロセスを実行します。

  • アプリケーション・ワークロードを分析し、それに応じて新しい索引を作成し、低パフォーマンスな既存の索引を削除して、データベース・パフォーマンスを向上させます。

  • ALTER TABLE MOVEなどの表パーティション化メンテナンス操作のために使用禁止とマークされている索引を再作成します。

  • データベースでの自動索引作成の構成、および自動索引作成操作に関連するレポートの生成のためのPL/SQL APIを提供します。

ノート:

  • 自動索引は、ローカルBツリー索引です。

  • 自動索引は、パーティション表および非パーティション表に対して作成できます。

  • 自動索引は、一時表に対しては作成できません。

  • 自動索引作成では、SQLパフォーマンス・アナライザ・フレームワークを内部的に使用してSQL文のパフォーマンスを測定します。SQL実行可能ファイルのリンク時にReal Application Testingが明示的に除外されていると、自動索引作成は機能しません。makeコマンドにRAT_OFFパラメータが指定されている場合、Real Application Testingは除外されます。Real Application Testingを明示的に除外し、自動索引作成を使用すると、エラー「ORA-00438: Real Application Testingのオプションがインストールされていません。」が生成されます。

20.7.2 自動索引作成の動作

この項では、自動索引作成がどのように機能するかを説明します。

自動索引作成プロセスは、バックグラウンドで15分ごとに実行され、次の操作を実行します。

  1. 自動索引候補の識別

    自動索引候補は、SQL文での表の列の使用方法に基づいて識別されます。

    表統計が最新であることを確認します。統計がない表は、自動索引付けの対象になりません。リアルタイム統計が使用できない場合、失効している統計を持つ表は、自動索引付けの対象になりません。

  2. 自動索引候補に対する不可視の自動索引の作成

    自動索引候補は、不可視の自動索引として作成されます。つまり、これらの自動索引は、SQL文で使用できません。

    自動索引は単一列にも複数列にもなります。これらは、次のもの対して考慮されます。

    • 表の列(仮想列を含む)
    • パーティション化された表およびパーティション化されていない表
    • 選択した式(JSON式など)
  3. SQL文に対する不可視の自動索引の検証

    不可視の自動索引は、SQL文に対して検証されます。

    これらの索引を使用することでSQL文のパフォーマンスが向上する場合、索引は、SQL文で使用できるように、可視索引として構成されます。

    これらの索引を使用してSQL文のパフォーマンスが向上しない場合、索引は非表示のままになります。

  4. 未使用の自動索引の削除

    長期間使用されていない自動索引は削除されます。

    ノート:

    デフォルトでは、未使用の自動索引は373日後に削除されます。データベース内の未使用の自動索引の保存期間は、DBMS_AUTO_INDEX.CONFIGUREプロシージャを使用して構成できます。

20.7.3 Oracle Databaseでの自動索引作成の構成

DBMS_AUTO_INDEX.CONFIGUREプロシージャを使用して、Oracleデータベースでの自動索引作成を構成できます。

次の例では、DBMS_AUTO_INDEX.CONFIGUREプロシージャを使用して指定できる構成設定のいくつかを説明します。

データベースでの自動索引作成の有効化および無効化

AUTO_INDEX_MODE構成設定を使用すると、データベースでの自動索引作成を有効または無効にできます。

次の文は、データベースでの自動索引作成を有効にし、新しい自動索引を可視索引として作成することで、SQL文で使用できるようにします。
EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_MODE','IMPLEMENT');
構成パラメータAUTO_INDEX_INCLUDE_DML_COSTを使用すると、オプティマイザは、自動索引付けを続行するかどうかをケースバイケースで決定できます。この決定は、自動索引付けのオーバーヘッドが、DMLアクティビティが大きいアプリケーションのパフォーマンスにどの程度悪影響を与えるかという評価に基づいています。次の文は、自動索引作成の実行時にDMLコスト認識を有効にします。
EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_INCLUDE_DML_COST','IMPLEMENT')

次の文は、データベースでの自動索引作成を有効にしますが、新しい自動索引を不可視索引として作成することで、SQL文で使用できないようにします。

EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_MODE','REPORT ONLY');

次の文は、データベースでの自動索引作成を無効にすることで、新しい自動索引が作成されないようにします(既存の自動索引は有効のまま)。

EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_MODE','OFF');

自動索引を使用できるスキーマの指定

AUTO_INDEX_SCHEMA構成設定を使用すると、自動索引を使用できるスキーマを指定できます。

ノート:

データベースで自動索引作成が有効になっている場合、そのデータベース内のすべてのスキーマはデフォルトで自動索引を使用できます。

次の文は、SHスキーマとHRスキーマを除外リストに追加し、SHスキーマとHRスキーマで自動索引を使用できないようにします。

EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_SCHEMA', 'SH', FALSE);
EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_SCHEMA', 'HR', FALSE);

次の文は、除外リストからHRスキーマを削除することで、HRスキーマが自動索引を使用できるようにします。

EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_SCHEMA', 'HR', NULL);

次の文は、除外リストからすべてのスキーマを削除することで、データベース内のすべてのスキーマが自動索引を使用できるようにします。

EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_SCHEMA', NULL, TRUE);

自動索引を使用できる表の指定

AUTO_INDEX_TABLE構成設定を使用すると、自動索引を使用できるスキーマを指定できます。スキーマに対して自動索引作成を有効にすると、そのスキーマ内のすべての表で自動索引を使用できます。ただし、スキーマ・レベルと表レベルの設定に競合がある場合は、表レベルの設定が優先されます。

次の文では、自動索引作成のためにSHスキーマにPRODUCTS表が含まれます。

EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_TABLE','SH.PRODUCTS',TRUE);

次の文では、SHスキーマ内のSALES表およびPRODUCTS表を除外リストに追加して、これらの表で自動索引を使用できないようにします。

EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_TABLE', 'SH.SALES', FALSE);
EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_TABLE', 'SH.PRODUCTS', FALSE);

次の文では、除外リストからSH.SALES表を削除して、表が自動索引を使用できるようにします。

EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_TABLE', 'SH.SALES', NULL);

次の文では、除外リストからすべての表を削除することで、データベース内のすべての表が自動索引を使用できるようにします。

EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_TABLE', NULL, TRUE);

次の文では、現在の構成設定をチェックします。

SELECT parameter_name, parameter_value FROM dba_auto_index_config WHERE parameter_name = 'AUTO_INDEX_TABLE';

未使用の自動索引の保存期間の指定

AUTO_INDEX_RETENTION_FOR_AUTO構成設定を使用すると、データベース内の未使用の自動索引を保存する期間を指定できます。未使用の自動索引は、指定した保存期間の後に削除されます。

ノート:

デフォルトでは、未使用の自動索引は373日後に削除されます。

次の文は、未使用の自動索引の保存期間を90日間に設定します。

EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_RETENTION_FOR_AUTO', '90');

次の文は、自動索引の保存期間をデフォルト値である373日間にリセットします。

EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_RETENTION_FOR_AUTO', NULL);

未使用の非自動索引の保存期間の指定

AUTO_INDEX_RETENTION_FOR_MANUAL構成設定を使用すると、データベース内の未使用の非自動索引(手動作成された索引)を保存する期間を指定できます。未使用の非自動索引は、指定した保存期間の後に削除されます。

ノート:

デフォルトでは、未使用の非自動索引が自動索引作成プロセスで削除されることはありません。

次の文は、未使用の非自動索引の保存期間を60日間に設定します。

EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_RETENTION_FOR_MANUAL', '60');

次の文は、未使用の非自動索引の保存期間をNULLに設定して、それらが自動索引作成プロセスによって削除されないようにします。

EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_RETENTION_FOR_MANUAL', NULL);

自動索引作成ログの保存期間の指定

AUTO_INDEX_REPORT_RETENTION構成設定を使用すると、データベース内の自動索引作成ログを保存する期間を指定できます。自動索引作成ログは、指定した保存期間の後に削除されます。

ノート:

デフォルトでは、自動索引作成ログは373日後に削除されます。

次の文は、自動索引作成ログの保存期間を60日間に設定します。

EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_REPORT_RETENTION', '60');

次の文は、自動索引作成ログの保存期間をデフォルト値である373日間にリセットします。

EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_REPORT_RETENTION', NULL);

ノート:

自動索引作成レポートは、自動索引作成ログに基づいて生成されます。したがって、AUTO_INDEX_REPORT_RETENTION構成設定を使用して指定された自動索引作成ログの保存期間を超える期間については、自動索引作成レポートを生成できません。

自動索引を格納する表領域の指定

AUTO_INDEX_DEFAULT_TABLESPACE構成設定を使用すると、自動索引を格納する表領域を指定できます。Oracle所有の表領域(SYSAUXなど)をデフォルトの表領域として指定することはできません。

ノート:

デフォルトでは、データベース作成時に指定された永続表領域が、自動索引の格納に使用されます。

次の文は、自動索引を格納するためにTBS_AUTO表領域を指定します。

EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_DEFAULT_TABLESPACE', 'TBS_AUTO');

自動索引用に割り当てる表領域の割合の指定

AUTO_INDEX_SPACE_BUDGET構成設定を使用すると、自動索引用に割り当てる表領域の割合を指定できます。この構成設定は、自動索引の格納に使用される表領域が、データベース作成時に指定されたデフォルトの永続表領域である場合(つまり、AUTO_INDEX_DEFAULT_TABLESPACE構成設定に値が指定されていない場合)にのみ指定できます。

次の文は、自動索引用に表領域の5パーセントを割り当てます。

EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_SPACE_BUDGET', '5');

自動索引の拡張索引圧縮の構成

AUTO_INDEX_COMPRESSION構成設定を使用して、自動索引で拡張索引圧縮を使用する必要があるかどうかを指定できます。拡張索引圧縮は、Oracle Advanced Compressionオプションの一部です。

次の例では、自動索引の作成時に拡張索引圧縮を有効にします。

EXEC DBMS_AUTO_INDEX.CONFIGURE('AUTO_INDEX_COMPRESSION','ON');

関連項目:

Oracle Advanced Compressionオプションの詳細は、『Oracle Databaseライセンス情報ユーザー・マニュアル』を参照してください。

関連項目:

DBMS_AUTO_INDEX.CONFIGUREプロシージャを使用して指定できる、自動索引作成に関連する構成設定の完全なリストは、Oracle Database PL/SQLパッケージおよびタイプ・リファレンスを参照してください。

20.7.4 自動索引作成レポートの生成

Oracleデータベースでの自動索引作成操作に関連するレポートを生成するには、DBMS_AUTO_INDEXパッケージのREPORT_ACTIVITYファンクションとREPORT_LAST_ACTIVITYファンクションを使用します。

関連項目:

DBMS_AUTO_INDEXパッケージのREPORT_ACTIVITYファンクションとREPORT_LAST_ACTIVITYファンクションの構文については、Oracle Database PL/SQLパッケージおよびタイプ・リファレンスを参照してください。

特定の期間の自動索引作成操作のレポートの生成

次の例では、過去24時間の自動索引作成操作について一般情報を含むレポートを生成します。デフォルトでは、このレポートはプレーン・テキスト形式で生成されます。

set linesize 130
set long 100000
set pagesize 0

var report clob
column report format a120

begin
  :report := DBMS_AUTO_INDEX.REPORT_LAST_ACTIVITY();
end;
/

select :report report from dual;

次の例では、2022年11月の自動索引作成操作について基本情報を含むレポートを生成します。このレポートはHTML形式で生成され、自動索引作成操作のサマリーのみを含んでいます。

set linesize 130
set long 100000
set pagesize 0

var report clob
column report format a120

begin
  :report := DBMS_AUTO_INDEX.REPORT_ACTIVITY(
               activity_start => TO_TIMESTAMP('2022-11-01', 'YYYY-MM-DD'),
               activity_end   => TO_TIMESTAMP('2022-12-01', 'YYYY-MM-DD'),
               type           => 'HTML',
               section        => 'SUMMARY',
               level          => 'BASIC');
end;
/

select :report report from dual;

最後の自動索引作成操作のレポートの生成

次の例では、最後の自動索引作成操作について一般情報を含むレポートを生成します。デフォルトでは、このレポートはプレーン・テキスト形式で生成されます。

set linesize 130
set long 100000
set pagesize 0

var report clob
column report format a120

begin
  :report := DBMS_AUTO_INDEX.REPORT_LAST_ACTIVITY();
end;
/

select :report report from dual;

次の例では、最後の自動索引作成操作について基本情報を含むレポートを生成します。このレポートには、最後の自動索引作成操作のサマリー、索引詳細およびエラー情報が表示されます。このレポートはHTML形式で生成されます。

set linesize 130
set long 100000
set pagesize 0

var report clob
column report format a120

begin
  :report := DBMS_AUTO_INDEX.REPORT_LAST_ACTIVITY(
               type           => 'HTML',
               section        => 'SUMMARY +INDEX_DETAILS +ERRORS',
               level          => 'BASIC');
end;
/

select :report report from dual;

20.7.5 自動索引作成情報を含むビュー

一連のデータ・ディクショナリ・ビューを問い合せて、Oracleデータベースでの自動索引に関する情報を取得できます。

次のビューには、自動索引作成の構成設定およびOracleデータベースで作成された自動索引に関する情報が示されます。

ビュー 説明
DBA_AUTO_INDEX_CONFIG

自動索引作成の現在の構成設定が示されます。

DBA_INDEXES
ALL_INDEXES
USER_INDEXES

これらのビューのAUTO列は、索引が自動索引であるかどうか(YES|NO)を示します。

関連項目:

これらのビューの完全な説明は、『Oracle Databaseリファレンス』を参照してください。

20.8 索引のデータ・ディクショナリ・ビュー

索引に関する情報について一連のデータ・ディクショナリ・ビューを問い合せることができます。

次のビューには、索引に関する情報が示されます。

ビュー 説明
DBA_INDEXES ALL_INDEXES USER_INDEXES

DBAビューには、データベース内のすべての表の索引に関する情報が示されます。ALLビューには、ユーザーがアクセスできるすべての表の索引に関する情報が示されます。USERビューは、ユーザーが所有する索引のみに制限されます。これらのビューの一部の列には、DBMS_STATSパッケージまたはANALYZE文によって生成される統計が含まれます。

DBA_IND_COLUMNS ALL_IND_COLUMNS USER_IND_COLUMNS

これらのビューには、表の索引の列に関する情報が示されます。これらのビューの一部の列には、DBMS_STATSパッケージまたはANALYZE文によって生成される統計が含まれます。

DBA_IND_PARTITIONS ALL_IND_PARTITIONSALL_IND_PARTITIONS USER_IND_PARTITIONS

これらのビューには、各索引パーティションについて、パーティションの詳細、パーティションの記憶域パラメータ、およびDBMS_STATSパッケージによって生成された様々なパーティション統計が示されます。

DBA_IND_EXPRESSIONS ALL_IND_EXPRESSIONS USER_IND_EXPRESSIONS

これらのビューには、表のファンクション索引の式に関する情報が示されます。

DBA_IND_STATISTICS ALL_IND_STATISTICS USER_IND_STATISTICS

これらのビューには、索引のオプティマイザ統計に関する情報が示されます。

INDEX_STATS INDEX_HISTOGRAM

これらのビューには、最後のANALYZE INDEX...VALIDATE STRUCTURE文に関する情報が示されます。

USER_OBJECT_USAGE

このビューには、ALTER INDEX...MONITORING USAGE文によって生成された索引使用情報が示されます。

関連項目:

これらのビューの完全な説明は、Oracle Databaseリファレンスを参照してください