Oracle:特定のSQLだけに特定のINDEXを使用させる方法 | けしくんのWebLog

けしくんのWebLog

自分が考えたこと、調べたことを忘れずに残しておくため、Web上にLogを残していきます。

特定のSQLにだけ使ってほしいINDEXを作りたいが、

それを作ってしまうと他のSQLに影響をしてしまうことがわかっていて、

INDEXを作るのを躊躇しまうことがある。

それに対応する方法。

 

よく使うOracle SQL/コマンドまとめ

 

以下のように対応する。

1.INDEXを「INVISIBLE」で作成する

2.作成したINVISIBLE INDEXを使用するSQLに対して、「USE_INVISIBLE_INDEXES」ヒント句を追加する

 

1.INDEXを「INVISIBLE」で作成する

CREATE INDEX文の最後に「INVISIBLE」をつけて作成するか、作成後、INVISIBLE属性に変更する。
INVISIBLE属性のINDEXは、オプティマイザから見えなくなり、使用されなくなる(注)。
 

CREATE INDEX 索引名 on テーブル名
( 列名,  列名, …)
TABLESPACE 表領域名
INVISIBLE;

 

ALTER INDEX 索引名 INVISIBLE;

(注) パラメータ「OPTIMIZER_USE_INVISIBLE_INDEXES」がFALSEの場合(デフォルト)の動作。

※「ALTER INDEX 索引名 VISIBLE;」を実行することで、通常のINDEXと同様にオプティマイザから見えるようになる。

 

2.作成したINVISIBLE INDEXを使用するSQLに対して、「USE_INVISIBLE_INDEXES」ヒント句を追加する

このヒント句を追加することで、通常は使用されないINVISIBLE INDEXがオプティマイザから見えるようになり、必要に応じてINDEXを使用するようになる。

複数のINVISIBLE INDEXがあった場合、それらすべてがこのヒント句を入れたSQL実行時に使用されてしまう可能性があるため、そのうちのこれだけ使用させたいという場合は、さらにINDEXヒントやNO_INDEXヒントを併用する。

 

(例)テーブルTBLにINDEXがIND_A、IND_B、IND_C(内BとCはINVISIBLE)が作成されており、実行するSQLに対してIND_BのINDEXを確実に使用させたい場合

 

SELECT /*+ USE_INVISIBLE_INDEXES
                    INDEX(TBL IND_B)
                    NO_INDEX(TBL IND_A TBL IND_C) */
列名, 列名, ...
FROM ...
WHERE ...;

※USE_INVISIBLE_INDEXESのみで事足りることが大半とは思われるため、INDEXヒントやNO_INDEXヒントは、どうしても思い通りの実行計画にならないときにつければ良い。

 

よく使うOracle SQL/コマンドまとめ