Oracleの仮想インデックスとは何ですか?
- 仮想インデックスは「偽の」インデックスであり、その定義はデータディクショナリに存在しますが、関連付けられたインデックスセグメントはありません。
- 多くの場合、SQLチューニングアドバイザーは、新しいインデックスを作成し、新しいインデックスをテストすることを推奨しています。この場合、大きなテーブルにインデックスを追加するのにかなりの時間がかかる可能性があり、テーブルが大きい場合にも大きなディスクスペースを消費します。また、追加のインデックスは他のセッションで使用できるため、他の部分のパフォーマンスに影響を与える可能性があります。現在テストしていないアプリケーションのこれは、実動システムの問題を特定しようとしているときに特に問題になる可能性があります。仮想インデックスはこの問題を解決します
- 仮想インデックスの目的は、実際に完全なインデックスを作成することなく、インデックスの存在をシミュレートすることです。
- これにより、開発者は、インデックスの作成が完了するのを待たずに、追加のディスクスペースを使用せずに、インデックスが存在するかのようにExplainプランを実行できます。
- 仮想インデックスを分析できます。
- 仮想インデックスを再構築することはできません。 ORA-8114をスローします:「ユーザーが偽のインデックスを変更しようとしました」
- 通常のインデックスと同じようにインデックスを削除できます。
SQL> drop index <index_name>;
覚えておくべき重要なポイント
(1)この機能を使用するには、セッションレベルで「_USE_NOSEGMENT_INDEXES」をtrueに設定する必要があります
(2)仮想インデックスは、インデックス作成スクリプトの最後にセグメントなしの部分を追加して作成されます
Oracleでの仮想インデックスの使用を示す例
(1)サンプルテーブルを作成します。たとえば、virtual_test_t
SQL> create table virtual_test_t as select * from dba_objects where rownum < 100000;
(2)表から任意の値を選択します
SQL> select * from virtual_test_t where object_name = 'FND_PROFILE';
(3)SELECTクエリのoracleExplainプランを確認します。
SQL> set autotrace traceonly explain
SQL> select * from virtual_test_t where object_name = 'FND_PROFILE';
Execution Plan
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 8 | 1416 | 156 (2)| 00:00:02 |
|* 1 | TABLE ACCESS FULL| VIRTUAL_TEST_T | 8 | 1416 | 156 (2)| 00:00:02 |
(4)作成したテーブルに仮想インデックスを作成します。
SQL> create index test_index_v on virtual_test_t(object_name) nosegment;
仮想インデックスを作成するには、CREATE INDEXステートメントでNOSEGMENT句を指定する必要があることに注意してください。
また、上記のステートメントを実行しても、インデックスセグメントは作成されません。
(5)以下で確認できます:
SQL> set autotrace off
SQL> select index_name from dba_indexes where table_name = 'VIRTUAL_TEST_T' and index_name = 'TEST_INDEX_V';
no rows selected
SQL> col OBJECT_NAME format a20;
SQL> select object_name, object_type from dba_objects where object_name = 'TEST_INDEX_V';
したがって、オブジェクトはデータベースに存在しますが、同じセグメントはありません。
(6)同じように実行して、インデックスが使用されているかどうかを確認します。
SQL> set autotrace traceonly explain
SQL> select * from virtual_test_t where object_name = 'FND_PROFILE';
Execution Plan
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 8 | 1416 | 156 (2)| 00:00:02 |
|* 1 | TABLE ACCESS FULL| VIRTUAL_TEST_T | 8 | 1416 | 156 (2)| 00:00:02 |
インデックスが使用されていないことがはっきりとわかります。
(7)作成された仮想インデックスを利用するには、_USE_NOSEGMENT_INDEXESパラメータをtrueに設定する必要があります。
SQL> alter session set "_USE_NOSEGMENT_INDEXES" = true;
Session altered.
(8)ここで、同じSELECTステートメントを実行します。
SQL> select * from virtual_test_t where object_name = 'FND_PROFILE';
Execution Plan
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 8 | 1416 | 5 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| VIRTUAL_TEST_T | 8 | 1416 | 5 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | TEST_INDEX_V | 216 | | 1 (0)| 00:00:01 |
この非表示パラメータを設定すると、Oracle Optimizerは、このテーブルで作成した仮想インデックスの使用を開始します。
他のセッションからこのクエリを実行すると、この仮想インデックスは使用されません(「alterセッション」ステートメント)。