7 拡張可能索引付けの使用

拡張可能索引付けを使用すると、Oracleに組み込まれている索引付けモード以外のモードを実装できます。拡張可能索引付けフレームワークを使用して作成される索引であるドメイン索引を作成する必要がある場合を考えます。

7.1 拡張可能索引付けの概要

索引作成のいくつかの条件と方法を考えます。この資料は、以前にデータベース・アプリケーションを操作したことがある開発者が理解しやすい内容になっています。

7.1.1 索引の目的

データベースに含まれるような大量のデータの場合、索引を使用するとデータの検索と取出しが高速かつ効率的になります。データベース内のレコードを参照するかテクニカル・マニュアルの本文を参照するかに関係なく、索引エントリは参照先項目について次の3つのことを示します。

  • 項目の内容(「Mary Leeの従業員情報」や「拡張可能索引付けの定義」など)

  • 項目の場所(「レコード番号1000」または「100ページ」など)

  • 項目の格納方法(「連続するレコード内」または「ページ本文」など)

ほとんどのデータ・セットは複数の異なる方法で索引付けできます。最も有用で効率的なデータ・アクセスを提供するには、通常、適切な索引付け形式を選択することが重要です。これは、すべてのアプリケーションにとって最適な索引付け方法は存在しないためです。

データベース・アプリケーションでは、通常は問合せを使用してデータを取得しますが、問合せでは、多くの場合、使用可能なデータのサブセットを選択するときに索引が使用されます。問合せを表すために使用される演算子は、問合せごとに大きく異なる場合があるため、最適なアクセスを提供する索引付けの方法も、大きく異なる場合があります。

  • サンフランシスコ支社に所属している営業担当を確認するには、等価性をチェックする演算子が必要です。ハッシュ構造では、等価演算子がきわめて効果的に処理されます。

  • 所得がxを超えていてy未満の営業担当を確認するには、範囲をチェックする演算子が必要です。範囲指向の問合せを処理するには、Bツリー構造の方が適しています。

7.1.2 拡張可能索引付けの目的

データベースには、医療アプリケーションやマルチメディア・アプリケーションのように、より複雑で特定のタスクに限定された新しいタイプの情報が継続的に取り込まれています。その結果、問合せはますます複雑になり、スキャンする必要のあるデータ量も増大を続けています。Oracleには拡張可能索引付けフレームワークが用意されているため、索引付け方法をデータとアプリケーションにあわせて調整でき、パフォーマンスと使いやすさを向上させることができます。

拡張可能索引付けを使用する場合、アプリケーションでは次の操作を実行します。

  • 索引の構造を定義します。

  • Oracleデータベース内(索引構成表形式など)またはOracleデータベース外に索引データを格納します。

  • 索引データを管理し、取り出してユーザー問合せの評価に使用します。

したがって、アプリケーションでは索引の構造とセマンティックの内容を制御することになります。データベース・システムはアプリケーションと共同でドメイン索引を作成、維持し、使用します。その結果、索引を作成して作業中のドメイン固有のタスクを実行でき、ユーザーは定義された演算子を使用して通常のような問合せを構成できます。

7.1.3 拡張可能索引付けを使用する場合

Oracleの組込み索引付け機能は、様々な状況に適しています。ただし、データが複雑になり、アプリケーションが特定のドメインにあわせて調整されると、他のアプローチを必要とする状況が生じてきます。たとえば、拡張可能索引付けは次のような問題の解決に役立ちます。

  • 特化された索引構造を使用した新規の検索演算子の実装

    演算子を定義し、索引構造を使用して特化された検索を実行できます。

  • 構造化されていないデータの索引付け

    組込み機能では、LOB値を含む列の索引付けはできません。

  • 列オブジェクトの属性の索引付け

    組込み機能では、列オブジェクトまたはコレクション型の要素の索引付けはできません。

  • ドメイン固有の操作から導出された値の索引付け

    Oracleオブジェクト型は、マップ・ファンクションまたは順序付けファンクションに匹敵します。オブジェクトでマップ・ファンクションが使用される場合は、関係述語の評価に使用するファンクション索引を定義できます。ただし、これが機能するのは有限範囲のパラメータを持つ述語の場合のみで、すべての行のファンクション値を事前計算できる必要があります。また、順序付けファンクションを使用して索引を構成することはできません。

7.1.4 索引構造

ドメイン索引の設計者に使用可能な選択肢を表す使用頻度の高い索引構造を考えてみます。

7.1.4.1 Bツリー

すべてのニーズを満たす索引構造はありませんが、単独で均衡を取ることができるBツリー索引は、大規模なデータ・セットの検索パフォーマンスを最適化するために最も適した選択肢です。Bツリーの各ノードには、複数のキーおよびポインタがあります。特定のBツリーがサポートするノードの最大キー数は、そのツリーの順序です。各ノードは、その下のレベルに対するポインタを、順序に1を足した個数だけ持つことができます。たとえば、図7-1に示されている順序が2のBツリーには、3つのポインタがあります。これらのポインタは、最初のキーより小さい値の子ノード、最初のキーより大きく2番目のキーより小さい値の子ノード、および2番目のキーより大きい値の子ノードを指します。このように、Bツリー・アルゴリズムでは、通過するノードの数をバイナリ・ツリー・アルゴリズム(各決定ノードのキーが1つのみで、子の数が最大2個)よりも少なくすることで、レコードを特定するために必要な読み書きの回数を最小限に抑えることができます。ここでは、索引が2つの部分で構成されるKnuthのバリエーションについて説明します。その構成要素の1つは、データへの高速順次アクセスを提供するシーケンス・セット、もう1つは、シーケンス・セットへの直接アクセスを提供する索引セットです。

通常、Bツリーのノードに同数のデータ値が含まれることはなく、使用されない領域が一定量含まれていますが、Bツリー・アルゴリズムではツリーのバランスが常にとれていることと、リーフ・ノードが同じレベルにあることが保証されます。

図7-1 Bツリー索引構造

図7-1の説明が続きます
「図7-1 Bツリー索引構造」の説明
7.1.4.2 ハッシュ

ハッシングは、特定のフィールド値に基づいて特定のストアド・レコードへの高速ダイレクト・アクセスを提供します。各レコードの格納位置のアドレスは、そのレコードのなんらかのフィールドのなんらかのファンクションとして計算されます。同じファンクションが挿入と取出しに使用されます。

ハッシングには、論理的な順序付けに関連する場合、レコードの物理的な順序付けが小さいという問題があります。また、ディスク上の未使用領域が大きくなる場合があります。

表7-2 ハッシュ索引構造

図7-2の説明が続きます
「図7-2 ハッシュ索引構造」の説明
7.1.4.3 k-dツリー

緯度と経度のような2つのディメンションを持つデータは、2-dツリーと呼ばれるk-dツリーのバリエーションを使用すると効率的に格納し、取り出すことができます。

この構造では、各ノードは情報フィールド、2つの座標、2つの子を指す左リンクと右リンクを持つデータ型です。

この構造は、範囲問合せに適しています。つまり、ユーザーが点(xx, xx)と距離を指定すると、問合せでは原点から指定した距離の範囲内にあるすべての点のセットが戻されます。

2-dツリーは実装が容易です。ただし、k個のノードを含む2-dツリーの高さはkになることがあるため、挿入および問合せが複雑になる可能性があります。

7.1.4.4 点quadtree

図7-4のように、点quadtreeも2次元空間における点データの表現に使用されますが、2-dツリーではリージョンが2つにわかれているのに対して、この種の構造ではリージョンが4つにわかれています。このノードのレコード・タイプのフィールドは、情報の属性、2つの座標および4つの子を指す4つの方位点(NW、SW、NE、SEなど)で構成されています。

図7-4 点quadtree索引構造

図7-4の説明が続きます
「図7-4 点quadtree索引構造」の説明

2-dツリーと同様に、点quadtreeは実装が容易です。ただし、k個のノードを含む点quadtreeの高さはkになることがあるため、挿入および問合せが複雑になる可能性があります。それぞれを比較するには、少なくとも2つの座標での比較が必要です。ただし、実際には点quadtreeの方がルートからリーフまでの長さが短くなる傾向があります。

7.2 拡張可能索引付けフレームワーク

拡張可能索引付けフレームワークは、ドメイン固有の演算子と索引付け方法を定義してOracleサーバーに統合できるSQLベースのインタフェースです。

拡張可能索引付けフレームワークは、次のコンポーネントで構成されています。

  • 索引タイプ: 索引タイプ・スキーマ・オブジェクトでは、アプリケーション固有の索引の定義、メンテナンスおよびスキャン操作を管理するルーチンを指定します。索引タイプにより、表の列またはオブジェクトの属性にユーザー定義索引を設定する方法をOracleサーバーに指示します。

  • ドメイン索引: 索引タイプを使用して作成されたアプリケーション固有の索引は、アプリケーション固有ドメインのデータに索引付けするため、ドメイン索引と呼ばれます。ドメイン索引は、索引タイプで指定したルーチンにより作成、管理およびアクセスされる索引のインスタンスです。

  • 演算子: 問合せおよびデータ操作文では、空間ドメインにおけるOverlaps演算子など、アプリケーション固有の演算子を使用できます。ユーザー定義演算子はファンクションにバインドされます。索引を使用して評価することもできます。たとえば、等価演算子はハッシュ索引を使用して評価できます。索引タイプは、定義対象となる演算子の索引ベース実装を提供します。

  • 索引構成表: 索引構成表を使用すると、アプリケーションで表のメタファを使用して複合オブジェクトの索引を定義、作成、メンテナンスおよびアクセスできます。アプリケーションには、索引は各行が索引エントリである表としてモデル化されます。索引構成表では重複する索引エントリが処理されますが、これが複合データ型には重要になる場合があります。

拡張可能索引付けフレームワークでは、次のアクションを実行できます。

  • アプリケーション固有の索引管理ルーチンを、索引タイプ・スキーマ・オブジェクトとしてカプセル化します。

  • 表列にドメイン索引を定義します。

  • アプリケーション固有の演算子を効率的に処理します。

拡張可能索引付けフレームワークを使用すると、他のOracle索引と同様に動作するドメイン索引を作成できます。ユーザーは、定義された演算子を使用して標準的な問合せを記述します。ドメイン索引の作成、削除、切捨て、変更および検索を行うために、索引タイプの一部として指定したアプリケーション・コードがOracleサーバーにより起動されます。

関連項目:

7.3 Text索引タイプの使用

Text索引タイプを使用して新規のテキスト索引付け方法を定義し、さらにText索引タイプを使用して、テキスト・データに索引付けおよび操作を実行する概略例を使用して、拡張可能索引付けフレームワークについて考えてみます。

7.3.1 索引タイプの定義

索引タイプのコンポーネントの作成順序は、索引ベースのファンクション実装を作成するかどうかに応じて異なります。

7.3.1.1 索引ベースでないファンクション実装

索引タイプ設計者がText索引タイプを定義する手順は、次のとおりです。

  1. サポートされている演算子のファンクション実装を定義してコーディングします。

    Text索引タイプは、Containsという演算子をサポートしています。この演算子は、テキスト値とキーを受け取り、そのテキストにそのキーが含まれているかどうかを示す数値を返します。この演算子のファンクション実装は、次のように定義される通常のファンクションです。

    CREATE FUNCTION TextContains(Text IN VARCHAR2, Key IN VARCHAR2)
    RETURN NUMBER AS
    BEGIN
    .......
    END TextContains;
    
  2. 新規の演算子を作成してファンクション実装にバインドします。
    CREATE OPERATOR Contains
     BINDING (VARCHAR2, VARCHAR2) RETURN NUMBER USING TextContains;
    
  3. 索引インタフェースODCIIndexを実装するタイプを定義します。

    そのためには、索引定義、索引メンテナンスおよび索引スキャンの各操作用のルーチンを実装する必要があります。Oracleは、次のルーチンをコールします。

    CREATE TYPE TextIndexMethods
    (
    STATIC FUNCTION ODCIIndexCreate(...)
    ...
    );
    CREATE TYPE BODY TextIndexMethods
    (
    ...
    );
    
  4. Text索引タイプのスキーマ・オブジェクトを作成します。

    索引タイプ定義では、新規の索引タイプでサポートされる演算子と、索引インタフェースを実装するタイプを指定します。

    CREATE INDEXTYPE TextIndexType
    FOR Contains(VARCHAR2, VARCHAR2)
    USING TextIndexMethods
    WITH SYSTEM MANAGED STORAGE TABLES;
7.3.1.2 索引ベースのファンクション実装

索引ベースのファンクション実装を作成する場合に実行する操作は、索引ベースでないファンクション実装の場合と同じですが、操作の順序が異なります。この順序が必要なのは、索引ベースのファンクション実装の定義には、パラメータとして実装タイプが必要となるためです。

  1. 実装タイプの定義
  2. ファンクション実装の定義とコーディング
  3. 演算子の作成
  4. 索引タイプの作成

7.3.2 索引タイプの使用

Text索引タイプを正しく定義したら、ユーザーはテキスト列にテキスト索引を定義し、Contains演算子を使用してテキスト・データを問い合せることができます。

MyEmployees表が例7-1の文によって定義されているとします。

resume列にテキスト・ドメイン索引を作成するには、例7-2の文を発行します。

resume列のテキスト・データを問い合せるには、例7-3のような文を発行します。問合せの実行では、resumeのテキスト索引を使用してContains条件が評価されます。

7.3.2.1 新しい表の宣言

例7-1 新しい表の宣言

CREATE TABLE MyEmployees
  (employee_id NUMBER(6), 
   first_name VARCHAR2(20), 
   last_name VARCHAR2(25), 
   salary NUMBER(8,2), 
   resume VARCHAR2(2000), 
   location VARCHAR2(200), 
   department_id NUMBER(4));
7.3.2.2 表のテキスト・ドメイン索引の作成

例7-2 テキスト・ドメイン索引の作成

CREATE INDEX ResumeIndex ON MyEmployees(resume) INDEXTYPE IS TextIndexType;
7.3.2.3 Contains()演算子を使用した表の問合せ

例7-3 Contains()演算子の使用

SELECT * FROM MyEmployees WHERE Contains(resume, 'Oracle') =1;