Oracle SQLチューニングの基本は実行計画を理解することです。実行計画はツリー構造で、様々なオペレーションから構成されます。
この記事では、INDEX RANGE SCANオペレーションについて説明します。
INDEX RANGE SCANオペレーションとはどのようなオペレーションか?
索引列の値を検索条件に指定したSQLで、索引にアクセスしたことを示すオペレーションです。索引にアクセスした結果、WHERE句の検索条件にマッチするデータが複数件返される可能性がある場合に使用されます。
オペレーション名から誤解されがちですが、SQLのWHERE句に BETWEEN … AND … を指定するような範囲条件を使用する必要はありません。
INDEX RANGE SCANオペレーションの”RANGE”とは、索引スキャンの結果得られる索引エントリが複数になる可能性があることを示します。よって、SQLのWHERE句に範囲条件以外の等価条件などを指定した場合でも、検索条件にマッチするデータが複数件返される可能性があれば、INDEX RANGE SCANオペレーションが使用されることがあります。
実行計画の例と処理イメージ図
- Id=2 INDEX RANGE SCAN : 索引を範囲検索して、検索条件に合致した行のROW IDのリストを得ます。
- Id=1 TABLE ACCESS BY INDEX ROWID : 索引スキャンの結果得た行のROW IDを元に、行が格納されているブロックにアクセスして、行データを得ます。
INDEX RANGE SCANオペレーションに関するFAQ
INDEX RANGE SCANオペレーションを使う実行計画は望ましくないですか?
一般に、テーブルに格納されたデータの件数が多く、そのテーブルから読み出すデータが大量の場合は、INDEX RANGE SCANオペレーションを使う実行計画は望ましくありません。
TABLE FULL ACCESSオペレーションなどの索引を用いないアクセスを行う実行計画になるように、SQLチューニングを行うと、性能が改善される可能があります。ただし、そもそも、テーブルから読み出すデータが大量である点が問題な場合は、TABLE FULL ACCESSオペレーションでも希望する所要時間までSQLチューニングできない場合もあります。
この場合は、単なる実行計画の変更ではなく、マテリアライズドビューを利用したり、あらかじめ検索結果を別途計算しておくなどの、テーブル設計/オブジェクト設計レベルの対処が必要となるケースもあります。
INDEX RANGE SCANオペレーションを使う実行計画に誘導するヒントは何ですか?
INDEXヒントです。以下にINDEXヒントを指定したSELECT文の例を示します。
-- 特定の索引の使用を指示する場合
SELECT /*+ index(<TABLE_NAME> <INDEX_NAME>) */ FROM ...
-- 指定された複数の索引から最適なコストの索引を使用するよう指示する場合
SELECT /*+ index(<TABLE_NAME> <INDEX_NAME1> <INDEX_NAME2> ... ) */ FROM ...
-- 索引の使用を指示し、どの索引を使用するかは指示しない場合
SELECT /*+ index(<TABLE_NAME>) */ FROM ...
INDEX RANGE SCANオペレーションの実行時、ブロックは1ブロックずつよみだされますか?
はい。索引のブロックは1ブロックずつよみだされます。ただし、対象となる索引のブロックがすでにメモリにキャッシュされている場合は、物理I/Oは発生しません。
検索条件にマッチするデータが常に1件の場合、どのオペレーションが使用されますか?
主キー制約または一意制約を設定した列の値を等価条件に指定したSQLの場合が該当します。この場合、INDEX UNIQUE SCANオペレーションが使用されます。
参考情報
キーワード
索引アクセス INDEX UNIQUE SCAN INDEX RANGE SCAN 索引レンジ・スキャン