索引は表およびクラスタと関連付けられているオプション構造で、これによりSQL問合せをより迅速に実行することができます。このマニュアルで、索引の使用により、索引がない場合よりも高速に情報を検索できるように、Oracle Databaseの索引は、表データへのより高速なアクセス・パスを提供します。索引は問合せをリライトすることなく使用できます。結果は同じですが、より高速に得られます。
この章は、次の情報を補足します。
『Oracle Database概要』の索引と索引構成表の説明
『Oracle Database管理者ガイド』の索引の管理に関する情報
Oracle Database SQLチューニング・ガイドの索引およびクラスタのパフォーマンス向上または低下方法の説明
内容は次のとおりです。
ここでは、索引の管理のガイドラインの概要を説明します。詳細は、『Oracle Database管理者ガイド』を参照してください。
表データの挿入後の索引の作成
正しい表および列の索引付け
パフォーマンスのための索引列の順序付け
表当たりの索引数の制限
不要な索引の削除
遅延セグメント作成の理解
索引サイズの見積りと記憶域パラメータの設定
索引ごとの表領域の指定
索引作成の並列化の検討
NOLOGGING
を使用する索引の作成の検討
使用禁止または非表示の索引をいつ使用するかの理解
索引の結合または再構築のコストとメリットの検討
制約を使用禁止または削除する前のコストの検討
『Oracle Database管理者ガイド』には、索引の管理に関する情報が含まれています。
索引の作成
索引の変更
索引の使用領域の監視
索引の削除
索引の情報を表示するデータ・ディクショナリ・ビュー
ドメイン索引(アプリケーション・ドメイン索引とも呼ばれます)はデータ・カートリッジ(検索エンジンまたは地理情報システムなど)を使用して実装されたアプリケーションに特有のカスタマイズされた索引です。ドメイン索引の詳細は、『Oracle Database概要』を参照してください。
参照: ドメイン索引をいつ構築するかを決定するための概念的背景については、『Oracle Databaseデータ・カートリッジ開発者ガイド』を参照してください。 |
ファンクション索引は1つまたは複数の列を含む式の値計算し、それを索引に格納します。索引式は、算術式、あるいはSQLファンクション、PL/SQLファンクション、パッケージ・ファンクションまたはCコールアウトを含む式のいずれかです。ファンクション索引は、照合キーに基づく言語ソート、SQL文の効率的な言語依存照合、および大/小文字を区別しないソートもサポートします。
ファンクション索引は索引式を使用する問合せのパフォーマンスを向上させます(特に式が計算集中型な場合)。ただし、次のことに注意してください。
データベースは索引を使用しない文の処理でも索引式を評価する必要があります。
頻繁に変更される列のファンクション索引は、データベースで維持するためにコストがかかります。
オプティマイザはファンクション索引をコストベースの最適化のためだけに使用できます。一方、列の索引はコストベースの最適化およびルールベースの最適化の両方のために使用できます。
内容は次のとおりです。
参照:
|
ファンクション索引には次のようなメリットがあります。
ファンクション索引により、データベースが全索引スキャン(『Oracle Database概要』を参照)のかわりに索引範囲スキャン(『Oracle Database概要』を参照)を実行できる機会が増加します。
WHERE
句によって大きな表の15%未満の行が選択された場合、索引範囲スキャンでは通常応答時間が短くなります。式がファンクション索引に実体化されていると、オプティマイザは式で選択される行数をより正確に見積もることができます。
Oracle Databaseでは索引式が仮想列として表されるので、ANALYZE
文(『Oracle Database SQL言語リファレンス』を参照)でヒストグラムを作成できます。
ファンクション索引は事前計算を行い、式の値を格納します。
問合せは式の値を計算するかわりに索引から得ることができます。値を必要とする問合せ、および計算集中型の索引式が増えれば増えるほど、索引によりアプリケーションのパフォーマンスは向上します(例9-1を参照してください。)
ファンクション索引はオブジェクト列またはREF
列に対して作成できます。
索引式はオブジェクト・タイプを戻すメソッドを起動することができます。詳細は、『Oracle Databaseオブジェクト・リレーショナル開発者ガイド』を参照してください(例9-2および『Oracle Database SQL言語リファレンス』の例を参照)。
ファンクション索引により、より強力なソートを実行できます。
索引式には、大/小文字を区別しないソートのためのSQLファンクションUPPER
およびLOWER
(例9-3を参照)、言語ベースのソートのためのSQLファンクションNLSSORT
(例9-4を参照)を含めることができます。
ファンクション索引には次のようなデメリットがあります。
オプティマイザはファンクション索引をコストベースの最適化のためだけに使用できます。ルールベースの最適化には使用できません。
コストベースの最適化はディクショナリに格納された統計情報を使用します。ファンクション索引の統計情報を収集するには、DBMS_STATS
.GATHER_TABLE_STATS
(『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照)またはDBMS_STATS
.GATHER_SCHEMA_STATS
(『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照)のいずれかを起動します。
ファンクション索引は、索引自体と索引が定義される表が分析されるまで、使用されません。
索引と索引が定義される表を分析するにはDBMS_STATS
.GATHER_TABLE_STATS
またはDBMS_STATS
.GATHER_SCHEMA_STATS
を起動します。
ファンクション索引は、OR
拡張が実行された場合、使用されません。
索引式が呼び出すすべてのスキーマ・レベルまたはパッケージ・レベルPL/SQLファンクションが、DETERMINISTICである(同じ入力に対して常に同じ結果を戻す)ことを確認する必要があります。
ファンクションはDETERMINISTIC
として宣言する必要がありますが、Oracle Databaseはこのアサーションをチェックしないので、ファンクションが実際にDETERMINISTICであることを確認する必要があります。
DETERMINISTIC
ファンクションのセマンティックを変更し、再コンパイルすると、依存するファンクション索引およびマテリアライズド・ビューを手動で再作成する必要があります。それ以外の場合は、旧バージョンのファンクションの結果がレポートされます。
索引式がファンクション起動の場合、ファンクションの戻り型は制約付きにできません。
ファンクションの戻り型をNOT
NULL
で制約できないため、索引を使用する問合せがNULL
値をフェッチできないことを保証する必要があります。そうしないと、データベースは全表スキャンを実行します。
索引式は集計ファンクションを呼び出すことができません(『Oracle Database SQL言語リファレンス』を参照)。
ビットマップ済のファンクション索引は、降順索引にはできません(『Oracle Database SQL言語リファレンス』を参照)。
索引式のデータ型は、VARCHAR2
、RAW
、LONGRAW
、または長さが不明のPL/SQLデータ型にはできません。
つまり、長さが不明な式には索引付けできません。ただし、そのような式の既知の長さのサブストリングには索引付けできます。次に例を示します。
CREATE OR REPLACE FUNCTION initials ( name IN VARCHAR2 ) RETURN VARCHAR2 DETERMINISTIC IS BEGIN RETURN('A. J.'); END; / /* Invoke SUBSTR both when creating index and when referencing function in queries. */ CREATE INDEX func_substr_index ON EMPLOYEES(SUBSTR(initials(FIRST_NAME),1,10)); SELECT SUBSTR(initials(FIRST_NAME),1,10) FROM EMPLOYEES;
参照:
|
例9-1は列a
、b
およびc
のある表を作成し、表に索引を作成し、表に問合せを実行します。索引は式a+b*(c-1)
を表す仮想列、列a
および列b
の3つの列に対するコンポジット索引です。問合せはそのWHERE
句に索引付けされた式を使用します。そのため、全索引スキャンのかわりに索引範囲スキャンを使用できます。
例9-1 算術式の事前計算用のファンクション索引
索引を作成する表を作成します。
DROP TABLE Fbi_tab; CREATE TABLE Fbi_tab ( a INTEGER, b INTEGER, c INTEGER );
索引を作成します。
CREATE INDEX Idx ON Fbi_tab (a+b*(c-1), a, b);
この問合せは全索引スキャンのかわりに索引範囲スキャンを使用できます。
SELECT a FROM Fbi_tab WHERE a+b*(c-1) < 100;
参照: 高速全索引スキャンの詳細は、『Oracle Database概要』を参照してください。 |
例9-2では、オブジェクト・タイプReg_obj
が定義され、そこに都市に関する情報が格納されると仮定します。例では、最初の列にタイプReg_obj
を含む表、パラメータにタイプReg_obj
を指定したDETERMINISTICファンクション、ファンクションを起動する2つのファンクション索引を作成します。最初の問合せは最初の索引を使用して赤道から1000マイル以上離れた都市を迅速に検索します。2番目の問合せは2番目の索引(コンポジット索引)を使用して、気温の差が20未満で最高気温が75よりも高い都市を迅速に検索します(表は例が移入されていないので問合せで行は戻りません )。
例9-2 オブジェクト列でのファンクション索引
オブジェクト列を含む表を作成します。
DROP TABLE Weatherdata_tab;
CREATE TABLE Weatherdata_tab (
Reg_obj INTEGER,
Maxtemp INTEGER,
Mintemp INTEGER
);
パラメータにタイプReg_obj
を指定したDETERMINISTICファンクションを作成します。
CREATE OR REPLACE FUNCTION Distance_from_equator ( Reg_obj IN INTEGER ) RETURN INTEGER DETERMINISTIC IS BEGIN RETURN(3000); END; /
最初のファンクション索引を作成します。
CREATE INDEX Distance_index
ON Weatherdata_tab (Distance_from_equator (Reg_obj));
問合せで索引式を使用します。
SELECT * FROM Weatherdata_tab WHERE (Distance_from_equator (Reg_Obj)) > '1000';
結果:
no rows selected
2番目のファンクション(コンポジット)索引を作成します。
CREATE INDEX Compare_index
ON Weatherdata_tab ((Maxtemp - Mintemp) DESC, Maxtemp);
問合せで索引式および索引付けされた列を使用します。
SELECT * FROM Weatherdata_tab WHERE ((Maxtemp - Mintemp) < '20' AND Maxtemp > '75');
結果:
no rows selected
例9-3では、EMPLOYEES
表でより高速な大/小文字を区別しない検索ができる索引を作成してから、問合せで索引式を使用します。
例9-3 大/小文字を区別しないより高速の検索用のファンクション索引
索引を作成します。
CREATE INDEX emp_lastname ON EMPLOYEES (UPPER(LAST_NAME));
問合せで索引式を使用します。
SELECT first_name, last_name
FROM EMPLOYEES
WHERE UPPER(LAST_NAME) LIKE 'J%S_N';
結果:
FIRST_NAME LAST_NAME -------------------- ------------------------- Charles Johnson 1 row selected.
例9-4では、1つの列NAME
を含む表、照合順序GERMAN
を使用して列をソートするファンクション索引を作成してから、表のすべての列を選択し、NAME
により順序付けします。問合せは索引を使用できるのでより高速です(問合せはドイツ語セッションで実行され、NLS_SORT
はGERMAN
、NLS_COMP
はANSI
であると仮定します。そうでない場合、問合せでこれらのグローバリゼーション・サポートのパラメータの値を指定する必要があります)。