6 XMLTypeデータの索引

頻繁に問い合せるXMLデータの特定部分に着目できるよう当該XMLデータに対して索引を作成し、パフォーマンスを向上できます。XML Schemaに基づくかどうか、および使用されるXMLType記憶域モデルに関係なく、XMLTypeデータに索引付けできる様々な方法があります。

注意:

ここで示す実行計画は、説明のためのみに使用しています。ここで示す例を実際の環境で実行しても、実行計画が同一になるわけではありません。

関連項目:

6.1 索引に関連するOracle XML DBのタスク

XMLデータの索引に関連する一般的なタスクについて説明します。

表6-1は、XMLデータの索引付けに関連するいくつかの基本的なユーザー・タスクの参照先を示します。

表6-1 基本的なXML索引付けタスク

操作の詳細 参照先

索引付けの方法の選択

XMLTypeデータの索引付けの概要

オブジェクト・リレーショナル形式で格納されたXMLTypeデータの索引付け

オブジェクト・リレーショナル形式で格納されたXMLTypeデータの索引付けガイドライン: Ordered Collection Tableに対する索引の作成

XMLIndex索引の作成、削除または名前の変更

例6-7例6-9

特定の表または列に対するXMLIndex索引名の取得

例6-8

指定されたXMLIndex索引を問合せの評価に使用するかどうかの判断

XMLIndexが使用されるかどうかを判別する方法

XMLIndex索引の使用の無効化

XMLIndexの使用の無効化

表6-2は、構造化コンポーネントを含むXMLIndex索引付けに関連するいくつかのユーザー・タスクの参照先を示します。

表6-2 構造化コンポーネントを含むXMLIndex索引に関連するタスク

操作の詳細 参照先

構造化コンポーネントが含まれるXMLIndex索引の作成

例6-23例6-21

XMLIndex索引の構造化コンポーネントの削除(すべての構造グループの削除)

例6-25

構造化コンポーネントが含まれるXMLIndex索引と問合せの間のデータ型の対応の確認

XMLIndex構造化コンポーネントのデータ型に関する考慮事項

XMLIndex構造化コンポーネントのコンテンツ表に対するBツリー索引の作成

例6-26

XMLIndex構造化コンポーネントのコンテンツ表に対するOracle Text CONTEXT索引の作成

例6-46

表6-3は、非構造化コンポーネントを含むXMLIndex索引付けに関連するいくつかのユーザー・タスクの参照先を示します。

表6-3 非構造化コンポーネントを含むXMLIndex索引に関連するタスク

操作の詳細 参照先

非構造化コンポーネントが含まれるXMLIndex索引の作成

例6-10例6-12例6-33例6-35例6-36例6-37例6-38

XMLIndex索引の非構造化コンポーネントの削除(パス表の削除)

例6-13

XMLIndex索引作成時の、パス表への名前付け

例6-10

XMLIndex索引作成時の、記憶域オプションの指定

例6-12

XMLIndexパス表にある既存の2次索引すべての表示

例6-14例6-20

XMLIndex索引に対するパス表名の取得

例6-11

パス表の指定による、非構造化コンポーネントが含まれるXMLIndex索引名の取得

例6-28

XMLIndexパス表に対する2次索引の作成

非構造化コンポーネントを含むXMLIndexの使用

XMLIndexパス表にあるすべての2次索引に関する情報の取得

例6-20

パス表のVALUE列に対するファンクション索引の作成

例6-15

パス表のVALUE列に対する数値索引の作成

例6-17

パス表のVALUE列に対する日付索引の作成

例6-18

パス表のVALUE列に対するOracle TextのCONTEXT索引の作成

例6-19

XMLIndex索引の使用における、特定のXPath式の除外または包含

XMLIndexパスのサブセット化: 索引付けするパスの指定

XMLIndexで使用されるXPath式のネームスペース接頭辞の指定

XMLIndexパスのサブセット化: 索引付けするパスの指定

XMLIndex索引の使用における、特定のXPath式の除外または包含

XMLIndexパスのサブセット化: 索引付けするパスの指定

XMLIndexで使用されるXPath式のネームスペース接頭辞の指定

XMLIndexパスのサブセット化: 索引付けするパスの指定

表6-4は、XMLIndex索引付けに関連するその他のユーザー・タスクの参照先を示します。

表6-4 XMLIndex索引に関連するその他のタスク

操作の詳細 参照先

XMLIndex索引の作成およびメンテナンスで並列処理を使用することの指定

XMLIndexのパーティション化および並列度

XMLIndexパス表の並列度の変更による、索引パフォーマンスのチューニング

XMLIndexのパーティション化および並列度

XMLIndex索引のメンテナンスのスケジュール

XMLIndex索引の非同期(遅延)メンテナンス

XMLIndex索引および実表の手動による同期化

XMLIndex索引の非同期(遅延)メンテナンス

コストベース・オプティマイザに対する表または索引に関する統計の収集

例6-40

XML検索索引の作成

例6-41

バイナリXMLとして格納されているXMLデータの全文検索におけるXML検索索引の使用

例6-42

XML検索索引が問合せで使用されているかどうかの表示

例6-43

XMLIndex構造化コンポーネントのコンテンツ表に対するOracle Text CONTEXT索引の作成

例6-46

6.2 XMLTypeデータの索引付けの概要

データベース索引では、表データに対するアクセスを高速化することにより、パフォーマンスが向上します。索引の使用は、更新が少ないオンライン・トランザクション処理(OLTP)環境に特に適しています。

XMLデータを索引付けする基本的な方法は、XMLIndexを使用することです。Oracle Text CONTEXT索引を使用して、XMLIndexの使用を補完することもできます。

バイナリXMLとして格納されているXMLTypeデータを索引付けする方法を選択するときに出発点となるサマリーのディシジョン・ツリーを次に示します。脚注1

XMLデータに、予測可能な構造化データのアイランドが含まれ、問合せが既知である場合

構造化コンポーネントXMLIndexを使用し、構造化アイランドを索引付けします(アイランドの周囲にあるのが非構造化データの場合も含みます)。

構造化された索引コンポーネントに、使用する問合せが反映されます。既知の問合せのセットは、一定期間に索引定義を正しく更新している場合に変更できます。XMLIndex構造化コンポーネントを参照してください。

XMLデータ内で全文コンテンツを問い合せる必要がある場合

XML検索索引を使用します。XMLデータのためのOracle Text索引を参照してください。

述語を含む非定型XML問合せをサポートする必要がある場合

非構造化コンポーネントXMLIndexを使用します。XMLIndex非構造化コンポーネントを参照してください。

(周囲のデータが構造化されていない可能性がある場合でも、) XMLデータに、高度に構造化された予測可能なデータのアイランドが含まれますか。

  • はい。構造化コンポーネントを含むXMLIndexを使用して、アイランドを索引付けします。「XMLIndex構造化コンポーネント」(6‐12ページ)を参照してください。

  • いいえ。XMLデータ内で全文コンテンツを問い合せる必要はありますか。

    • はい。XML検索索引を使用します。「XMLデータのためのOracle Text索引」(6‐5ページ)を参照してください。

    • いいえ。述語を含む非定型XML問合せをサポートする必要はありますか。その場合は、非構造化コンポーネントを含むXMLIndexを使用します。「XMLIndex非構造化コンポーネント」(6‐16ページ)を参照してください。それ以外の場合は、XMLデータを索引付けする必要はありません。

6.2.1 XMLIndexによるXMLデータのファイングレイン構造の対処

1つ以上のリレーショナル列または1つのファンクション式に対して、索引を作成できます。XMLデータには独自のファイングレイン構造がありますが、その構造は、XMLデータが格納されるデータベース表の構造に必ずしも反映されるとはかぎりません。このような理由から、XMLデータに効果的に索引付けする方法は、他の大部分のデータベース・データに対する索引付けとは多少異なります。

オブジェクト・リレーショナル形式のXMLType記憶域では、要素や属性などのXMLオブジェクトはオブジェクト・リレーショナル列および表に対応しています。これらの列および表に対してBツリー索引を作成する方法は、対応するXMLオブジェクトに効果的に索引付けする場合に最適です。この場合、記憶域モデルはXMLデータのファイングレイン構造を直接反映するため、構造化XMLデータの索引付けにおいて特別な問題は生じません。オブジェクト・リレーショナル形式で格納されたXMLTypeデータの索引付けを参照してください。

オブジェクト・リレーショナル形式のXMLType記憶域では、XML文書が分割され、オブジェクト・リレーショナル形式で格納されますが、1つ以上のXMLフラグメントを埋込みのCLOBインスタンスとして格納するように選択できます。通常はフラグメント全体が1つの単位としてアクセスされるため、このような場合は通常、XML SchemaのcomplexTypeまたは複合要素をCLOB記憶域にマッピングします。

ただし、このような埋込みのCLOBフラグメントは、索引付けの際には不透明型の単位としても機能し、個々の部分には索引付けされません。

標準的な索引付けも同様に、バイナリXML記憶域には有効ではありません。いずれの場合も、標準的な索引(Bツリー、ビットマップ)を使用してデータベース列に索引付けすると、多くの場合、XML文書の特定部分にアクセスする際に問題が生じます。

XMLIndexは通常のXML固有の索引により、XMLデータの内部構造に索引付けします。その主な目的の1つとして、バイナリXML記憶域によって課される索引付けの制限を克服することがあげられます。

  • 非構造化コンポーネントを含むXMLIndex索引では、文書のXMLタグに索引付けし、それをターゲットとするXPath式に基づいて文書のフラグメントを識別します。また、スカラー・ノードのに対して索引付けすることで、単独の値または値の範囲に基づく高速参照も可能にします。さらに、索引付けする各ノードに対し、文書の階層情報(親と子、祖先と子孫、および兄弟の関係)を記録します。この索引コンポーネントは、構造が少ない文書または可変構造を持つ文書からXMLフラグメントを抽出する問合せで特に便利です。

  • 構造化コンポーネント含むXMLIndex索引では、ほとんどの部分が構造化されていないXMLデータでも、高度に構造化された予測可能な部分に索引付けします。この索引コンポーネントは、構造化コンテンツのアイランドを投影および使用する問合せで特に便利です。

関連トピック

6.2.2 XMLデータのためのOracle Text索引

要素や属性などのXMLノードにアクセスする以外にも、XMLテキスト・ノード内の特定の節に対して高速アクセスを提供する必要があることがあります。XMLデータ内でこのようなコンテンツの問合せを行うには、XQuery Full Text (XQFT)またはOracle固有の全文構造体を使用できます。

いずれの場合も、適切なOracle Text (全文)索引が作成されます。XQFTの場合、索引はXML検索索引であり、バイナリXMLとして格納されたXMLTypeデータでの使用に特化した設計になっています。

全文索引は、特に、XML要素とテキストノード・コンテンツが混在する、文書中心のアプリケーションにおいて有用です。全文検索は、構造化XML検索と組み合せる(XPath式によって識別されるXML文書の一定部分に対して検索を限定する)ことによってさらに強力に、焦点を絞って行えるようになります。

6.2.3 最適化による、使用する適切な索引の選択

1つのケースで複数の索引が該当する場合は、どの索引が使用されるでしょうか。パフォーマンスを最大化する索引(複数可)は、コストベースの最適化によって決定されます。

Oracle Text索引はテキストにのみ適用されるため、XMLデータではテキスト・ノードを意味します。テキスト・ノードがターゲットとされ、対応するOracle Text索引が定義されている場合は、Oracle Text索引が使用されます。特定のコンテキストにおいて他の索引も適している場合は、これらも使用されます。ただし、単に索引が定義され、特定の状況に適用可能に見えることは、必ずしもその索引が使用されことを意味しません。コストベース・オプティマイザによって費用効率が低いと判断されたものは、使用されません。

6.2.4 XMLTypeに対するファンクション索引の非推奨化

Oracle Database 11gリリース2(11.2)以前のリリースでは、XPath式が単一ノードをターゲットにしている場合、XMLTypeデータにおいてファンクション索引の使用が適していることもありました。かわりに、XMLIndexの構造化コンポーネントを使用することをお薦めします。

これにより、ファンクション索引のメンテナンス操作に関連するオーバーヘッドを軽減し、オプティマイザで索引を適切に選択できる状況が増えます。その結果、既存のDML文の変更が不要になります。

さらに、XMLTypeのオブジェクト・リレーショナル記憶域では、Oracle SQL関数extractValue (非推奨)で索引を定義すると、XPathリライトにより、(extractValueに対してファンクション索引ではなく)基礎のオブジェクトに対してBツリー索引が自動的に作成されることがあります。XPathのターゲットは単一の要素または属性である必要があります。XMLQueryに適用されるXMLCastに対しても、同様のショートカットが存在します。

6.3 XMLIndex

6.3.1 XMLIndexの利点

オブジェクト・リレーショナル形式のXMLType記憶域では、Bツリー索引を効果的に使用できます。基礎となるオブジェクトを直接ターゲット化することで、焦点がより明確に絞られます。ただし、バイナリXMLを使用して格納されているXML文書の詳細な構造(要素および属性)を指定する場合、通常は効果を発揮しません。これはXMLIndexの特殊ドメインです。

XMLIndexドメイン索引で、XMLデータのドメイン用に特化して設計されています。これは論理的索引です。XMLIndex索引は、SQL/XML関数XMLQueryXMLTableXMLExistsおよびXMLCastに対して使用できます。

XMLIndexには、他の索引付け方式に比べ、次のような利点があります。

  • XMLIndex索引は、問合せのどの部分においても効果があります。つまり、WHERE句での使用に限定されません。これは、XMLデータで使用される他の種類の索引では考えられません。

  • 非構造化コンポーネントを含むXMLIndex索引では、SELECTリスト・データとFROMリスト・データの両方に対するアクセスを高速化でき、特にXMLフラグメント抽出において有用です。ファンクション索引は非推奨になったため、文書のフラグメントの抽出には使用できません。

  • XMLIndex索引は、XML Schemaに基づく/基づかないにかかわらず、バイナリXMLとして格納されているXMLTypeデータに対して使用できます。Bツリー索引は、オブジェクト・リレーショナル形式で格納されるXML Schemaに基づくデータにのみ適しています。

  • XMLIndex索引は、コレクション(文書内に複数回出現するノード)をターゲットとするXPath式による検索において使用できます。ファンクション索引の場合とは異なります。

  • 問合せに使用されるXPath式に関する事前の知識は不要です。XMLIndex索引の非構造化コンポーネントは、汎用性に富んでいます。ファンクション索引の場合とは異なります。

  • 問合せに使用されるXPath式が事前にわかっている場合は、頻繁に問合せされる構造化された固定のデータ・アイランドをターゲットとする構造化XMLIndexコンポーネントを使用することで、パフォーマンスを向上できます。

  • XMLIndex索引(索引の作成とメンテナンス)は、複数のデータベース処理により、並列的に実行できます。非推奨になったファンクション索引の場合とは異なります。

6.3.2 構造化XMLIndexコンポーネントと非構造化XMLIndexコンポーネント

XMLIndexを使用して非構造化または半構造化のXMLデータ(一般的にほとんどまたはまったく固定構造を持たないデータ)を索引付けします。それは、バイナリXMLとして格納されるXMLTypeデータに適用されます。

それでも、半構造化XMLデータには、予測可能な構造化データ・アイランドが含まれることがあります。そのため、XMLIndex索引は、そのようなアイランドの索引付け用の構造化コンポーネントと、ほとんど構造を持たないまたは可変構造のデータの索引付け用の非構造化コンポーネントの2つのコンポーネントを持つことができます。

構造化コンポーネントは、構造化コンテンツのアイランドを投影および使用する問合せで使用すると役立ちます。典型的な例は、作成者、日付およびタイトルの固定フィールドを持つ書式自由の仕様です。非構造化コンポーネントは、XMLフラグメントを抽出する問合せで使用すると役立ちます。1つのXMLIndex索引に、必ずしも両方のコンポーネントが含まれている必要はありません。

構造化コンポーネントとは異なり、非構造化コンポーネントは汎用的で、比較的ターゲットを限定しません。文書中心のXMLデータの一般的な索引付けに適しています。典型的な例は、1つのXML Webドキュメント、または書籍のうちの1章です。

XMLIndex索引は、構造化コンポーネントと非構造化コンポーネントのどちらでも作成できます。典型的なユースケースは、構造化データも存在するときは常に文書からXMLフラグメントを抽出するような問合せをサポートする場合などがあります。非構造化コンポーネントは、フラグメントの抽出に使用されます。構造化コンポーネントは、構造化データを確認する問合せ述語(たとえば、SQLのWHERE句など)に使用されます。

特定のXPathサブセットにのみ適用されるように非構造化コンポーネントを制限することもできますが、そのパス表索引ノードの内容のスカラー型が異なる場合は、異なるデータ型を処理するようにVALUE列に対して複数の2次索引を作成する必要があることがあります(VALUE列に対する2次索引を参照)。また、非構造化コンポーネントのみを使用した場合、構造化アイランドを投影する問合せに対してプローブやそのパス表の自己結合が何度も行われるために、効率が悪くなることがあります。

一方、構造化コンポーネントは、ほとんど構造を持たない問合せや、XMLフラグメントを抽出する問合せには適していません。構造化データ・アイランドの索引付けには構造化コンポーネントを使用し、ほとんど構造を持たないデータの索引付けには非構造化コンポーネントを使用してください。

最後の行はXMLIndexがXMLデータの様々なユースケースに適用できるかどうかを示します。XMLIndexが半構造化XMLデータ(格納されているかどうかに関係なくに)適していることを示します(最後の3列)。構造化コンポーネントでのXMLIndex索引は、構造化アイランドを含むドキュメント中心データに有用です(4列目)。

図6-1 XMLのユースケースとXML索引付け

図6-1の説明が続きます
「図6-1 XMLのユースケースとXML索引付け」の説明

関連項目:

XMLIndexコンポーネント・タイプで提供される利点の概要は、XMLIndexの利点参照してください。

6.3.3 XMLIndex構造化コンポーネント

XMLコンテンツの固定の構造化アイランドを投影する問合せに対しては、周囲のデータが比較的構造化されていない場合でも、XMLIndex索引の構造化コンポーネントを作成して使用します。

構造化XMLIndexコンポーネントは、このようなアイランドをリレーショナル形式で編成します。この場合、これはSQL/XML関数XMLTableと類似しており、構造化コンポーネントの定義に使用する構文も類似しています。索引付けデータの格納に使用するリレーショナル表はデータ型を認識し、各列は異なるスカラー・データ型を持つことができます。

したがって、XMLIndex索引の構造化コンポーネントを作成することは、XMLデータの構造化部分をリレーショナル形式へ分解することと考えることができます。これは、次のような点でXMLTypeのオブジェクト・リレーショナル形式の記憶域モデルとは異なります。

  • 構造化索引コンポーネントは、指定されたデータの特定の部分(頻繁に問い合せる部分)を明示的に分解します。オブジェクト・リレーショナル形式のXMLType記憶域の場合は、XMLType表または列全体が自動的に分解されます。

  • XMLIndex索引の構造化コンポーネントは、XML Schemaに基づくデータにもXML Schemaに基づかないデータにも適用できます。オブジェクト・リレーショナル形式のXMLType記憶域は、XML Schemaに基づくデータにのみ適用できます。

  • 構造化XMLIndexコンポーネントに対して分解されたデータは、XMLTypeデータ自体の記憶域モデルとしてではなく索引として、XMLTypeデータとともに格納されます。

  • 構造化XMLIndexコンポーネントに対しては、同じデータを、データ型が異なる列として何度も投影できます。

XMLIndex索引の構造化コンポーネントに使用する索引コンテンツ表は索引の一部ですが、通常のリレーショナル表なので、標準的なリレーショナル索引(主キーおよび外部キー制約を満たす索引を含む)を使用すれば、これらの表にも索引を作成できます。また、Oracle Text CONTEXT索引などのドメイン索引を使用して索引を作成することもできます。

また、XMLIndex索引の構造化コンポーネントは、汎化ファンクション索引として考えることもできます。ファンクション索引は、リレーショナル列を1つのみ持つ構造化XMLIndexコンポーネントのようなものです。

特定のアプリケーションに対して複数のファンクション索引を作成することを予定している場合、かわりに構造化コンポーネントを持つXMLIndex索引の使用を検討してください。また、構造化索引コンポーネントの列にBツリー索引も作成します。

注意:

  • SQL/XML関数XMLTableを使用する問合せは通常、XMLIndex構造化コンポーネントのリレーショナル索引付け表を使用するように自動的にリライトすることができます。特に、SQLのORDER BYGROUP BY、およびXMLTable仮想表の列を操作するウィンドウ構造体が、構造化されたXMLIndexコンポーネントのリレーショナル索引付け表の実際の列を操作する同じ構造体にリライトされます。

    XMLIndex構造化索引付けに使用されるリレーショナル表には、システム定義の内部列も含まれています。これらの内部列は将来的に変更される可能性があるため、その存在や内容を前提とするようなコードは記述しないでください。

  • SQL TABLEコレクション式内のOracle SQL関数XMLSequence (TABLE(XMLSequence(...)))を使用する問合せは、XMLIndex構造化コンポーネントの索引付け表を使用するようにリライトされません。Oracle SQL関数XMLSequenceは、Oracle Database 11gリリース2で非推奨になりました。かわりに、標準のSQL/XML関数XMLTableを使用してください。

    SQL TABLEコレクション式の詳細は、Oracle Database SQL言語リファレンスを参照してください。

6.3.3.1 透過的な索引コンテンツ表の無視

XMLIndex構造化コンポーネントの索引コンテンツ表は通常のリレーショナル表ですが、読取り専用の表でもあるため、表の列を追加または削除したり、表の行を変更(挿入、更新または削除)したりすることはできません。

したがって、通常はリレーショナル索引コンテンツ表は無視してかまいません。DESCRIBEしたり、(2次)索引を作成する以外、それらにアクセスできません。それらに関する統計を明示的に収集する必要はありません。XMLIndex索引自体、またはXMLIndex索引が定義されている実表に関する統計のみ収集する必要があります。索引コンテンツ表に関する統計は透過的に収集され保持されます。

6.3.3.2 XMLIndex構造化コンポーネントのデータ型に関する考慮事項

XMLIndex構造化コンポーネントに使用されるリレーショナル表では、SQLデータ型が使用されます。問合せ内で使用されるXQuery式では、XMLデータ型(XML Schemaデータ型およびXQueryデータ型)が使用されます。

一貫性や型チェックを保証するために、XQueryの入力規則の部分式のデータ型が自動的に変わることがあります。たとえば、XPath式/PurchaseOrder/LineItem[@ItemNumber = 25]を使用して問合せされる文書がXML Schemaに基づいていない場合、部分式@ItemNumberは型なしとなり、XQueryの比較演算子=によって自動的にxs:doubleにキャストされます。XMLIndex構造化コンポーネントを使用してこのデータに索引を作成するには、SQLデータ型としてBINARY_DOUBLEを使用する必要があります。

これは通例です。構造化コンポーネントを含むXMLIndex索引を問合せに適用するには、データ型が対応している必要があります。表6-5に、対応するデータ型を示します。

表6-5 XMLIndexでのXMLデータ型とSQLデータ型の対応

XMLデータ型 SQLデータ型

xs:decimal

INTEGERまたはNUMBER

xs:double

BINARY_DOUBLE

xs:float

BINARY_FLOAT

xs:date

DATETIMESTAMP WITH TIMEZONE

xs:dateTime

TIMESTAMPTIMESTAMP WITH TIMEZONE

xs:dayTimeDuration

INTERVALDAYTOSECOND

xs:yearMonthDuration

INTERVALYEARTOMONTH

注意:

XMLデータ型がxs:dateまたはxs:dateTimeの場合、索引を作成する問合せ対象のデータにタイムゾーン・コンポーネントが含まれていないことがわかっていれば、SQLデータ型DATEまたはTIMESTAMPを使用するとパフォーマンスを高めることができます。データにタイムゾーン・コンポーネントが含まれている可能性がある場合は、SQLデータ型TIMESTAMP WITH TIMEZONEを使用する必要があります。

対象となるXMLデータ型とSQLデータ型に1対1の組込みの対応関係がない場合は、問合せに対して索引が取得されるように、(表6-5に従って)両者を対応させる必要があります。これには、次の2つの方法があります。

  • 索引を問合せに対応させる: 構造化索引コンポーネント内の列を、XMLデータ型と対応するように定義(または再定義)します。たとえば、索引付けの対象となる問合せにXMLデータ型xs:doubleを使用するには、対応するSQLデータ型BINARY_DOUBLEを使用するように索引を定義します。

  • 問合せを索引に対応させる: 問合せ内で、XQuery式の関連部分を、索引コンテンツ表に使用するSQLデータ型と対応するデータ型に明示的にキャストします。

例6-1および例6-2に、問合せ内でXQuery式をキャストして、索引コンテンツ表に使用するSQLデータ型に一致させる方法を示します。

この2つの例では、数字25はどちらも受注品目番号ですが、それぞれ異なる役割を果しています。例6-1では25はデータ型INTEGERのSQL数値であり、例6-2では25はデータ型xs:decimalのXQuery数値です。

例6-1では、XMLQueryの結果がSQLのINTEGER型にキャストされ、SQLの値25と比較されます。例6-2では、属性ItemNumberの値がXMLデータ型xs:decimalに(XQuery内で)キャストされます。これはXQueryの値25と比較され、索引に使用されるSQLデータ型(INTEGER)に対応します。このように、この例では2つの異なる種類のデータ型の変換が行われますが、どちらも型が索引コンテンツ表と一致するように問合せデータが変換されます。

関連項目:

XML Schemaデータ型とSQLデータ型の組込みの対応関係の詳細は、DBMS_XMLSCHEMAを使用したXML Schemaデータ型のSQLデータ型へのマッピングを参照してください。

例6-1 問合せデータと索引データを対応させる: SQLのキャスト

SELECT count(*) FROM purchaseorder
  WHERE XMLCast(XMLQuery('$p/PurchaseOrder/LineItem/@ItemNumber'
                         PASSING OBJECT_VALUE AS "p" RETURNING CONTENT)
                AS INTEGER)
        = 25;

例6-2 問合せデータと索引データを対応させる: XQueryのキャスト

SELECT count(*) FROM purchaseorder
  WHERE XMLExists('$p/PurchaseOrder/LineItem[xs:decimal(@ItemNumber) = 25]'
                  PASSING OBJECT_VALUE AS "p");
6.3.3.3 パーティション交換とXMLIndex

パーティション交換では、1つの表と、別の表のパーティションを変更します。最初の表には、交換対象となる2番目の表のパーティションと同じ構造が含まれている必要があります。2つの表はXMLIndex索引による索引付けという点でも類似している必要があります。

次の条件の1つに該当している必要があります。

  • どちらの表にもXMLIndex索引がないこと。

  • どちらにもXMLIndex索引があり、次のいずれかが当てはまること。

    • どちらの索引にも構造化コンポーネントがない。

    • どちらの索引にも構造化コンポーネントがある。

これらの条件のいずれも当てはまらない場合、パーティション交換は実行できません

どちらの表でも構造化コンポーネントにXMLIndex索引がある場合は、通常、ALTER TABLE EXCHANGE PARTITIONを呼び出す前に一定の前処理を実行する必要があり、呼出し後にも一定の後処理を実行する必要があります。そうしないと、exchange-partition操作でエラーが発生します。

この前処理と後処理を実行するには、例6-3のようにパッケージDBMS_XMLSTORAGE_MANAGEのPL/SQLプロシージャexchangePreProcexchangePostProcを使用します。XMLTypeの各表、tableexchange_tableには、構造化コンポーネントを持つXMLIndex索引があります。

参照パーティション表の特殊なケースでは、外部キー制約が関連するため、状況は少し複雑になります。この場合、PL/SQLプロシージャrefPartitionExchangeInまたはrefPartitionExchangeOutをそれぞれ使用して、データをパーティション表にロード(exchange-in)またはパーティション表からロード(exchange-out)します。

例6-4では、交換対象の表parent_exおよびchild_exから実表parentおよびchildにデータをロードし、これを示します。例6-5に、表と索引の定義を示します。

関連項目:

例6-3 XMLIndex構造化コンポーネントを持つ表のパーティション交換

EXEC DBMS_XMLSTORAGE_MANAGE.exchangePreProc(USER, 'table');
EXEC DBMS_XMLSTORAGE_MANAGE.exchangePreProc(USER, 'exchange_table');

ALTER TABLE table EXCHANGE PARTITION partition WITH TABLE exchange_table
  WITH VALIDATION UPDATE INDEXES;

EXEC DBMS_XMLSTORAGE_MANAGE.exchangePostProc(USER, 'table');
EXEC DBMS_XMLSTORAGE_MANAGE.exchangePostProc(USER, 'exchange_table');

例6-4 XMLIndexを使用する参照パーティション表のパーティション交換

この例の各要素の意味は次のとおりです。

  • parentは、パーティション実表です。

  • childは、XMLTypexcolを含む子の参照パーティション表です。

  • child_xidxは、表childの列xcolに定義された構造化コンポーネントを含むXMLIndex索引です。これは、パーティション化されたローカル索引です。

  • parent_exは、実表parentの交換対象の表です。

  • child_exは、子表childの交換対象の表です。

  • child_xidx_exは、表child_exの列xcolに定義された構造化されたコンポーネントを含むXMLIndex索引です。これは、(索引child_xidxの場合とは異なり)ローカル索引ではありません

  • USERは、表の所有者(データベース・スキーマ)です。

この例ではexchange-in操作を実行して、交換対象の表からパーティション表にデータをロードします。パーティション表から交換対象の表にデータをロードするexchange-out操作は、同じ操作のように見えますが、かわりにプロシージャrefPartitionExchangeOutを使用することが異なります。このプロシージャに、関連する表と必要なALTER TABLE ... EXCHANGE文が渡されます。

EXEC DBMS_XMLSTORAGE_MANAGE.refPartitionExchangeIn(
       USER, 'parent', 'child', 'parent_ex', 'child_ex',
       'ALTER TABLE parent EXCHANGE PARTITION part_all WITH TABLE parent_ex
          INCLUDING INDEXES WITH VALIDATION UPDATE INDEXES',
       'ALTER TABLE child  EXCHANGE PARTITION part_all WITH TABLE child_ex
          INCLUDING INDEXES WITH VALIDATION UPDATE INDEXES');

例6-5 参照パーティション表のパーティション交換の例で使用されるデータ

この例は、例6-4で使用される表と索引の作成操作を示しています。

CREATE TABLE parent (id      NUMBER PRIMARY KEY,
                     created DATE)
  PARTITION BY RANGE (created)
    (PARTITION part_2014 VALUES LESS THAN (to_date('01-jan-2015', 'dd-mon-yyyy')),
     PARTITION part_all  VALUES LESS THAN (maxvalue));
CREATE TABLE child (parent_id NUMBER NOT NULL,
                    xcol      XMLType,
                    CONSTRAINT child_tab_fk FOREIGN KEY (parent_id)
                                            REFERENCES parent (id)
                    ENABLE VALIDATE)
  XMLType COLUMN xcol STORE AS BINARY XML PARTITION BY REFERENCE (child_tab_fk);
CREATE INDEX child_xidx ON child p (xcol) INDEXTYPE IS XDB.XMLIndex
  PARAMETERS ('XMLTable po_index_tab ''purchaseorder''
               COLUMNS pid NUMBER(4) PATH ''@id''') LOCAL ;
CREATE TABLE parent_ex (id      NUMBER PRIMARY KEY,
                        created DATE);
CREATE TABLE child_ex (parent_id NUMBER NOT NULL,
                       xcol      XMLType,
                       CONSTRAINT child_tab_fk1 FOREIGN KEY (parent_id)
                                                REFERENCES parent_ex(id)
                      ENABLE VALIDATE)
  XMLType COLUMN xcol STORE AS BINARY XML;
CREATE INDEX child_ex_xidx ON child_ex p (xcol) INDEXTYPE IS XDB.XMLIndex
  PARAMETERS ('XMLTable po_index_tab_ex ''purchaseorder''
               COLUMNS pid NUMBER(4) PATH ''@id''');

6.3.4 XMLIndex非構造化コンポーネント

Bツリー索引は、個々のXML要素または属性を表す特定のデータベース列や、構造化ドキュメントの特定部分に適用されるXMLIndex構造化コンポーネントに対して定義します。これに対し、XMLIndex索引の非構造化コンポーネントは、デフォルトで非常に汎用性に富んでいます。

索引付けに使用する特定のXPath式や使用しない特定のXPath式を限定することにより焦点を絞り込んだ場合を除き、非構造化XMLIndexコンポーネントはXMLデータのすべての使用可能なXPath式に適用されます。

XMLIndex索引の非構造化コンポーネントは、次の3つの論理部分で構成されます。

  • パス索引: 文書のXMLタグを索引付けし、様々な文書のフラグメントを識別します。

  • 順序索引: XML文書におけるノードの階層的な位置を索引付けします。親と子、祖先と子孫、および兄弟の関係を追跡します。

  • 値索引: XML文書のを索引付けします。値の等価性または値の範囲による参照が可能です。値索引は、問合せ述語(WHERE句)の値に使用されます。

XMLIndex索引の非構造化コンポーネントは、パス表と、そのパス表の一連の(ローカルの)2次索引を使用します。これらは前述の論理部分を実装します。2つの2次索引が自動的に作成されます。

  • pikey索引: パスおよび順序の両方の論理索引を実装します。

  • 値索引: 論理値の索引を実装します。

これらの2つの索引を変更したり、追加の2次索引を作成できます。パス表とその2次索引はすべて、XMLIndex索引が作成される実表の所有者によって所有されます。

pikey索引は、パスと順序の関係を処理し、ほとんどの場合で最適なパフォーマンスが得られます。値索引を取得すべきときに取り出されない場合は、パスおよび順序の関係で個別の索引をpikey索引のかわりに使用できます。このような(オプション)の索引は、それぞれパスID索引および順序キー索引と呼ばれます。特定の場合の要件でpikey索引が不十分の場合は、最適な結果を得るためにOracleサポートに問い合せてください。

パス表では、XML文書で索引付けされる1つのノードに対して1行が使用されます。索引付けされたノードごとに、パス表には次のものが格納されます。

  • 文書を格納する表に対応するROWID

  • 対応する文書のフラグメントへの高速アクセスを提供するロケータ。XML Schemaに基づくデータのバイナリXML記憶域については、データ型情報も格納します。

  • 文書におけるノードの階層的な位置を記録するための順序キー。これは、図書目録やインターネット・プロトコルSNMPで使用されるような、デューイ10進分類キーのようなものです。このようなシステムでは、3.21.5というキーは、文書のルート・ノードの3番目の子の21番目の子の5番目の子というノード位置を表します。

  • ノードに対するXPathパスを表す識別子。

  • ノードの有効なテキスト値

表6-6に、パス表に含まれる主な情報脚注 2を示します。

表6-6 XMLIndexのパス表

データ型 説明

PATHID

RAW(8)

ノードのXPathパスに対する一意の識別子です。

RID

ROWID

XMLデータを格納するために使用される表のROWIDです。

ORDER_KEY

RAW(1000)

ノードの階層的な位置を識別するための、10進数の順序キーです。(ドキュメントの順序は保持されます。)

LOCATOR

RAW(2000)

フラグメント位置情報です。フラグメント抽出に使用されます。XML Schemaに基づくデータのバイナリXML記憶域では、データ型情報もここに格納されます。

VALUE

VARCHAR2(4000)

ノードの有効テキスト値。

pikey索引では、パス表の列PATHIDRIDおよびORDER_KEYを使用して、パスと順序の索引を表します。オプションのパスID索引では、列PATHIDおよびRIDを使用して、パス索引を表します。値索引は、VALUE列に対する索引です。

例6-6では、2つの発注書のパス表の内容を見ていきます。

例6-6 2つの発注書のパス表の内容

<PurchaseOrder>
 <Reference>SBELL-2002100912333601PDT</Reference>
 <Actions>
  <Action>
   <User>SVOLLMAN</User>
  </Action>
 </Actions>
 . . .
</PurchaseOrder>

<PurchaseOrder>
 <Reference>ABEL-20021127121040897PST</Reference>
 <Actions>
  <Action>
   <User>ZLOTKEY</User>
  </Action>
  <Action>
   <User>KING</User>
  </Action>
 </Actions>
 . . .
</PurchaseOrder>

これらの発注書を格納するXMLType表または列のXMLIndex索引には、XML文書で索引付けされたノードに対し、1行ずつ使用するパス表が含まれます。仮に、XPath式に従ってノードに索引付けする際、システムによって次のPATHIDが割り当てられるとします。

PATHID 索引付けされたXPath

1

/PurchaseOrder

2

/PurchaseOrder/Reference

3

/PurchaseOrder/Actions

4

/PurchaseOrder/Actions/Action

5

/PurchaseOrder/Actions/Action/User

結果として作成されるパス表は、次のようになります(LOCATOR列は示されません)。

PATHID RID ORDER_KEY VALUE

1

R1

1

SBELL-2002100912333601PDTSVOLLMAN

2

R1

1.1

SBELL-2002100912333601PDT

3

R1

1.2

SVOLLMAN

4

R1

1.2.1

SVOLLMAN

5

R1

1.2.1.1

SVOLLMAN

1

R2

1

ABEL-20021127121040897PSTZLOTKEYKING

2

R2

1.1

ABEL-20021127121040897PST

3

R2

1.2

ZLOTKEYKING

4

R2

1.2.1

ZLOTKEY

5

R2

1.2.1.1

ZLOTKEY

4

R2

1.2.2

KING

5

R2

1.2.2.1

KING

6.3.4.1 表パスは透過的であり、無視

パス表の列に2次索引を作成した場合でも、パス表そのものは通常は無視できます。

パス表には、それをDESCRIBEしたり、(2次)索引を作成したりする以外はアクセスできません。パス表に関する統計を明示的に収集する必要はありません。統計は、XMLIndex索引、またはXMLIndex索引が定義されている実表についてのみ収集する必要があります。統計は収集され、パス表と2次索引に透過的に保持されます。

6.3.4.2 XMLIndexパス表のVALUE列

VALUE列の2次索引は、一致する文字列に関する述語を有するWHERE句のXPath式で使用されます。例:

/PurchaseOrder[Reference/text() = "SBELL-2002100912333601PDT"]

VALUEには、要素または属性ノードの有効テキスト値が格納されます。索引付けの際、コメントおよび処理命令は無視されます。

  • 属性では、有効テキスト値は属性値です。

  • 単純な要素(子のない要素)では、有効テキスト値は、要素のすべてのテキスト・ノードを連結したものになります。

  • 複雑な要素(子のある要素)では、有効テキスト値は、(1)要素そのもののテキスト・ノードを連結したもの、(2)単純要素のすべての子孫の有効テキスト値になります。(これは再帰的定義です。)

ただし、有効テキスト値は4000バイト(単純な要素または属性の場合)および80バイト(複雑な要素の場合)に制限(切捨て)されます。

VALUE列のサイズは、VARCHAR2(4000)に固定されています。索引の作成または更新時のオーバーフロー(4000バイト超)は、すべて切り捨てられます。

VALUE列に対する4000バイトの上限に加え、当該列に対して作成される2次索引のキーのサイズにも制限があります。これは、Bツリー索引とファンクション索引にも該当します。XMLIndexの制限ではありません。索引キーのサイズの限界は、データベースのブロック・サイズの関数です。VALUEに対してどの程度の索引付けがなされるかは、この制限値によって決定します。

つまり、有効テキスト値の最初の4000バイトのみがVALUE列に格納され、VALUE列の最初のNバイトに対してのみ索引が作成されるということです。ここでNとは、索引キーのサイズの制限を表します(N < 4000)。索引キーのサイズの制限が課されることにより、VALUE列の索引は、有効テキスト値の事前フィルタとしてのみ機能します。

たとえば、データベースのブロック・サイズにより、VALUE列の索引を800バイト以内に抑え、有効テキスト値のうち最初の800バイト分のみを索引付けするとします。有効テキスト値の最初の800バイト分に対してXMLIndexを使用してテストを実行し、そのテキスト接頭辞が問合せ値に一致した場合のみ、残りの有効テキスト値がテストされます。

VALUE列の2次索引は、substr SQL関数(サブストリング等価性)です。この関数を使用して、テキスト接頭辞をテストするためです。このファンクション索引は、VALUE列に対するXMLIndexの実装の一環として自動的に作成されます。

たとえば、問合せのWHERE句のXPath式/PurchaseOrder[Reference/text() = :1]は、実質的に、次のようなテストにリライトされることがあります。

substr(VALUE, 1 800) = substr(:1, 1, 800) AND VALUE = :1;

この結合は2つの部分から構成され、左から右に向かって処理されます。1つ目のテストでは、substr関数の索引を事前フィルタとして使用し、冒頭800バイトがバインド変数:1の冒頭800バイトに一致しないテキストを削除します。

索引は、1つ目のテストでのみ使用されます。VALUE列の完全な値は索引付けされません。1つ目のテストで事前フィルタリングを実行した後、2つ目のテストで有効テキスト値全体をチェックします。つまり、VALUE列の完全な値と、:1の値の等価性を確認します。このチェックでは索引は使用されません。

テキストの冒頭800バイトのみが索引付けされる場合でも、問合せパフォーマンスでは、最大4000バイトをVALUE列に格納することが重要になります。これにより、CLOBインスタンスのXML文書内の深い部分からデータを抽出することなく、データに迅速かつ直接的にアクセスできるようになるからです。有効テキスト値が4000バイトを超える場合は、WHERE句結合の2つ目のテストにおいて、実表データにアクセスする必要があります。

VALUE列に対する4000バイト上限も、索引キーのサイズも、問合せ結果には何の影響も与えません。これらはパフォーマンスにのみ影響を与えます。

注意:

VALUEに対して作成されたOracle Text CONTEXT索引は、VALUE列が切り捨てられることがあるために、間違った結果を戻す可能性があります。

前述したように、XMLIndexはXML Schemaに基づくデータで使用できます。XML Schemaが特定の要素または属性に対してdefaultValue値を指定し、特定の文書が当該の要素または属性に対して値を指定しない場合、defaultValue値がVALUE列で使用されます。

6.3.4.3 VALUE列に対する2次索引

XMLIndex索引を作成する際、VALUE列に対して2次索引を指定しない場合でも、VALUE列に対してデフォルトの2次索引が作成されます。このデフォルト索引には、デフォルトのプロパティがあります。具体的には、これはtext(文字列値)データでのみ使用される索引です。

ただし、異なる種類のVALUE索引を作成できます。たとえば、数値の索引が問合せの大半に適している場合は、数値の索引を作成できます。VALUE列に対し、複数の2次索引を作成できます。特定の種類の索引は、それが適切な場合にのみ使用されます。たとえば、数値の索引は、VALUE列が数値である場合にのみ使用されます。その他の値の場合は無視されます。パス表の列の2次索引は、その他の2次索引と同様に扱われます。つまり、これらの索引は変更、削除、不使用としてマーキングするなどが可能です。

関連項目:

6.3.4.4 XMLIndex非構造化コンポーネントによって索引付けされないXPath式

いくつかのタイプのXPath式は、XMLIndexにより索引付けされません

  • ora:contains (非推奨)以外のXPath関数の適用。特に、ユーザー定義のXPath関数は索引付けされません

  • childdescendant、およびattribute以外の軸(parentancestorfollowing-siblingpreceding-siblingfollowingpreceding、およびancestor-or-selfの各軸)。

  • 共用体演算子|(垂直バー)を使用する式。

6.3.5 XMLIndex索引の作成、削除、変更、および検証

XMLIndex索引に対する基本操作には、XMLIndex索引の作成、削除、変更および検証が含まれます。例を示します。

例6-7に示すように、索引タイプをXDB.XMLIndexと宣言して、XMLIndex索引を作成します。

これにより、XMLTypepo_binxml表に、po_xmlindex_ixという名前のXMLIndex索引が作成されます。索引に含まれるのは非構造化コンポーネントのみで、構造化コンポーネントは含まれません。

XMLIndex索引に構造化コンポーネントを含めるように指定するには、PARAMETERS句にstructured_clauseを含めます。非構造化コンポーネントを含めるように指定するには、PARAMETERS句にpath_table_clauseを含めます。

この操作は、XMLIndex索引を作成または変更する場合に可能です。例6-7に示すように、structured_clausepath_table_clauseのいずれも指定しない場合は、非構造化コンポーネントのみが含まれます。

XMLIndex索引に非構造化コンポーネントと構造化コンポーネントの両方が含まれる場合は、ALTER INDEXを使用していずれかのコンポーネントを削除できます。

例6-8に示すように、特定のXMLType表(または列)のXMLIndex索引の名前を取得できます。また、適宜DBA_INDEXESまたはALL_INDEXESからINDEX_NAMEを選択することも可能です。

例6-9に示すように、XMLIndex索引は、他の索引と同様に名前変更または削除できます。この名前変更では、XMLIndex索引の名前のみが変更されます。この処理ではパス表の名前は変更されません。パス表は、個別に名前を変更できます。

同様に、REBUILDなどのALTER INDEXオプションを使用し、他の索引プロパティも変更できます。この点においては、XMLIndexも他の索引タイプと同じです。

XMLIndexALTER INDEX文のRENAME句は、XMLIndexそのものに対してのみ適用されます。パス表および2次索引の名前を変更するには、これらのオブジェクトの名前を決定し、適切なALTER TABLE文またはALTER INDEX文を直接使用する必要があります。同様に、2次索引の物理プロパティを取得したり、他のなんらかの方法で変更を加えたりする場合は、例6-14の方法に従って2次索引の名前を取得する必要があります。

例6-7 XMLIndex索引の作成

CREATE INDEX po_xmlindex_ix ON po_binxml (OBJECT_VALUE) INDEXTYPE IS XDB.XMLIndex;

例6-8 特定の表にあるXMLIndex索引の名前の取得

SELECT INDEX_NAME FROM USER_INDEXES
  WHERE TABLE_NAME = 'PO_BINXML' AND ITYP_NAME = 'XMLINDEX';

INDEX_NAME
---------------
PO_XMLINDEX_IX
 
1 row selected.

例6-9 XMLIndex索引の名前変更と削除

ALTER INDEX po_xmlindex_ix RENAME TO new_name_ix;

DROP INDEX new_name_ix;

6.3.6 非構造化コンポーネントを含むXMLIndexの使用

非構造化コンポーネントを含むXMLIndex索引に対して、該当コンポーネントのパス表や2次索引の操作など、様々な操作を実行できます。

XMLIndex索引に非構造化コンポーネントを含めるには、XMLIndex索引の作成または変更時に、PARAMETERS句でpath_table_clauseを使用できます。path_table_clause ::=を参照してください。

構造化コンポーネントを指定しない場合、パス表を指定しなくても、索引に非構造化コンポーネントが含まれます。ただし、一般的にはパス表を指定することをお薦めします。これにより他のXMLIndex操作で参照できる、ユーザー指向の認識可能な名前が含まれるようになります。

例6-10に、非構造化コンポーネントを含むXMLIndex索引の作成時に、パス表(my_path_table)の名前を付ける方法を示します。

パス表に名前を付けなかった場合、名前はCREATE INDEXに与えた索引名に基づき、システムによって自動的に生成されます。例6-11に、例6-7で作成したXMLIndex索引を使用した例を示します。

デフォルトでは、パス表と2次索引の記憶域オプションは、XMLIndex索引が作成された実表の記憶域プロパティから生成されます。例6-12で示すように、索引の作成時にPARAMETERS句を使用すると、異なる記憶域オプションを指定できます。CREATE INDEX (およびALTER INDEX)のPARAMETERS句は、一重引用符(')で囲む必要があります。

XMLIndexは論理的なドメイン索引であり、物理索引ではないため、すべての物理属性はゼロ(0)またはNULLになります。

XMLIndex索引に非構造化コンポーネントと構造化コンポーネントの両方が含まれる場合は、ALTER INDEXを使用して非構造化コンポーネントを削除できます。これを実行するには、パス表を削除します。例6-13に、これを示します。(この場合は、構造化コンポーネントも含むことを前提とします。例6-23では、索引に構造化コンポーネントと非構造化コンポーネントの両方が含まれるようになります。)

例6-12では、パス表に対する記憶域オプションの指定に加え、パス表に対する2次索引にも名前を付けています。

パス表の名前と同様、パス表の列の2次索引の名前は、PARAMETERS句で指定しないかぎり、索引名をベースとして使用して自動的に生成されます。例6-14にこれを示します。これらの名前をパブリック・ビューUSER_IND_COLUMNSで決定する方法も示します。また、pikey索引で3つの列を使用することも示します。

関連項目:

例6-20に、類似するが、さらに複雑なケースを示します。

例6-10 XMLIndex索引のパス表への名前付け

CREATE INDEX po_xmlindex_ix ON po_binxml (OBJECT_VALUE) INDEXTYPE IS XDB.XMLIndex
  PARAMETERS ('PATH TABLE my_path_table');

例6-11 XMLIndexパス表のシステム生成名の決定

SELECT PATH_TABLE_NAME FROM USER_XML_INDEXES
  WHERE TABLE_NAME = 'PO_BINXML' AND INDEX_NAME = 'PO_XMLINDEX_IX';
 
PATH_TABLE_NAME
------------------------------
SYS67567_PO_XMLINDE_PATH_TABLE
 
1 row selected.

例6-12 XMLIndex索引の作成時における記憶域オプションの指定

CREATE INDEX po_xmlindex_ix ON po_binxml (OBJECT_VALUE) INDEXTYPE IS XDB.XMLIndex
  PARAMETERS
    ('PATH TABLE po_path_table
      (PCTFREE 5 PCTUSED 90 INITRANS 5
       STORAGE (INITIAL 1k NEXT 2k MINEXTENTS 3 BUFFER_POOL KEEP)
       NOLOGGING ENABLE ROW MOVEMENT PARALLEL 3)
      PIKEY INDEX po_pikey_ix (LOGGING PCTFREE 1 INITRANS 3)
      VALUE INDEX po_value_ix (LOGGING PCTFREE 1 INITRANS 3)');

例6-13 XMLIndex非構造化コンポーネントの削除

ALTER INDEX po_xmlindex_ix PARAMETERS('DROP PATH TABLE');

例6-14 XMLIndex索引の2次索引の名前付け

SELECT INDEX_NAME, COLUMN_NAME, COLUMN_POSITION FROM USER_IND_COLUMNS
  WHERE TABLE_NAME IN (SELECT PATH_TABLE_NAME FROM USER_XML_INDEXES
                         WHERE INDEX_NAME = 'PO_XMLINDEX_IX')
  ORDER BY INDEX_NAME, COLUMN_NAME;
 
INDEX_NAME                     COLUMN_NAME  COLUMN_POSITION
------------------------------ ------------ ---------------
SYS67563_PO_XMLINDE_PIKEY_IX   ORDER_KEY                  3
SYS67563_PO_XMLINDE_PIKEY_IX   PATHID                     2
SYS67563_PO_XMLINDE_PIKEY_IX   RID                        1
SYS67563_PO_XMLINDE_VALUE_IX   SYS_NC00006$               1
 
4 rows selected.
6.3.6.1 XMLIndexパス表に対する追加の2次索引の作成

XMLIndex非構造化コンポーネントに、2次索引をさらに追加できます。

例6-15例6-17例6-18および例6-19の各例では、例6-12で作成されたXMLIndex索引に、2次索引をさらに追加します。

XMLIndex索引のパス表のVALUE列に対し、2次索引をいくつでも追加で作成できます。ファンクション索引やOracle Text索引など、様々な種類が可能です。

問合せの処理時に、指定の索引が指定の要素に対して使用されるかどうかは、その索引が当該値に対して適切であるかどうかや、その索引の使用が費用効率に優れているかどうかによって決まります。

例6-15では、SQL関数substrを使用して、パス表のVALUE列にファンクション索引を作成します。問合せにおいて、XML要素のテキスト・ノードに対してsubstrがよく使用される場合は便利な方法です。

テキスト・ノードが数値を表す要素が多数ある場合、VALUE列に対して数値索引を作成すると有効です。ただし、例6-15と同じような方法で数値索引を直接作成すると、要素値のいずれかが数値ではない場合にORA-01722エラー(無効な数値)が発生します。これを例6-16に示します。

ここで必要となるのは、数値の要素に対して使用されるが、数値を持たない要素に対しては無視される索引です。特に、DBMS_XMLINDEXパッケージのcreateNumberIndexプロシージャは、この目的でのみ存在するものです。このプロシージャに、データベース・スキーマの名前、XMLIndex索引、および作成される数値索引を渡します。数値索引の作成は、例6-17に示します。

このような索引は数値を持たない要素を無視するよう設計されているため、この索引が数値を持たない要素を検出することはありません。非数値要素がある場合に、なんらかの理由によりXMLIndex索引が問合せで使用されなければ、ORA-01722エラーが発生します。ただし、索引が使用されると非数値データは無視されるため、エラーは発生しません。ここでも、索引の使用により結果セットが変わることはありません。結果はまったく同じですが、索引を使用すると、誤ったデータの検出を防ぐことはできます。

日付値の索引の作成は、数値索引の作成と似ています。この場合は、DBMS_XMLINDEX.createDateIndexプロシージャを使用します。例6-18に、これを示します。

例6-19では、Oracle TextのCONTEXT索引をVALUE列に作成します。これは、XML要素のテキスト値に対する全文問合せにおいて便利です。XPath関数ora:contains (非推奨)を使用するXPath述語は、VALUE列のcontains Oracle SQL関数を適用するようにリライトされます。CONTEXT索引がVALUE列に対して定義されている場合、述語の評価時に使用されます。Oracle Text索引は、他のすべてのVALUE列の索引に依存しません。

例6-20の問合せは、XMLIndex索引のパス表に対して作成されたすべての2次索引を示します。作成された索引は、明確に太字で示されます。特に注意する必要があるのは、VALUE列に作成されたファンクション索引などは、この例のように表示されない点です。これらの索引の列名は、SYS_NC00007$などのシステム生成名になります。そのため、WHERE句でCOLUMN_NAME = 'VALUE'を使用して問合せを実行しても、これらの列を見ることはできません

関連項目:

例6-15 パス表のVALUE列に対するファンクション索引の作成

CREATE INDEX fn_based_ix ON po_path_table (substr(VALUE, 1, 100));

例6-16 パス表のVALUE列に対する、数値索引の直接作成

CREATE INDEX direct_num_ix ON po_path_table (to_binary_double(VALUE));
CREATE INDEX direct_num_ix ON po_path_table (to_binary_double(VALUE))
                                             *
ERROR at line 1:
ORA-01722: invalid number

例6-17 createNumberIndexプロシージャによる、VALUE列に対する数値索引の作成

CALL DBMS_XMLINDEX.createNumberIndex('OE', 'PO_XMLINDEX_IX', 'API_NUM_IX');

例6-18 createDateIndexプロシージャによる、VALUE列に対する日付索引の作成

CALL DBMS_XMLINDEX.createDateIndex('OE', 'PO_XMLINDEX_IX', 'API_DATE_IX', 
                                   'dateTime');

例6-19 パス表のVALUE列に対するOracle Text CONTEXT索引の作成

CREATE INDEX po_otext_ix ON po_path_table (VALUE)
  INDEXTYPE IS CTXSYS.CONTEXT PARAMETERS('TRANSACTIONAL');

例6-20 XMLIndexのパス表上にある、すべての2次索引の表

SELECT c.INDEX_NAME, c.COLUMN_NAME, c.COLUMN_POSITION, e.COLUMN_EXPRESSION
  FROM USER_IND_COLUMNS c LEFT OUTER JOIN USER_IND_EXPRESSIONS e
    ON (c.INDEX_NAME = e.INDEX_NAME)
  WHERE c.TABLE_NAME IN (SELECT PATH_TABLE_NAME FROM USER_XML_INDEXES
                           WHERE INDEX_NAME = 'PO_XMLINDEX_IX')
  ORDER BY c.INDEX_NAME, c.COLUMN_NAME;
 
INDEX_NAME           COLUMN_NAME  COLUMN_POSITION COLUMN_EXPRESSION
-------------------- ------------ --------------- ----------------------
API_DATE_IX          SYS_NC00009$               1 SYS_EXTRACT_UTC(SYS_XMLCONV("V
                                                  ALUE",3,8,0,0,181))
API_NUM_IX           SYS_NC00008$               1 TO_BINARY_DOUBLE("VALUE")
FN_BASED_IX          SYS_NC00007$               1 SUBSTR("VALUE",1,100)
PO_OTEXT_IX          VALUE                      1
PO_PIKEY_IX          ORDER_KEY                  3
PO_PIKEY_IX          PATHID                     2
PO_PIKEY_IX          RID                        1
PO_VALUE_IX          SYS_NC00006$               1 SUBSTRB("VALUE",1,1599)
 
8 rows selected.

6.3.7 構造化コンポーネントを含むXMLIndexの使用

XMLIndex構造化コンポーネントにより、XMLデータ内の構造の特定のアイランドを索引付けします。

XMLIndex索引に構造化コンポーネントを含めるには、XMLIndex索引の作成または変更時に、PARAMETERS句でstructured_clauseを使用します。structured_clause ::=を参照してください。

structured_clauseでは、索引付けの対象となる構造化アイランドを指定します。キーワードGROUPを使用して、各構造化アイランドを指定します。このためアイランドの構文は構造グループに一致します。明示的にグループを指定しない場合、事前定義済グループDEFAULT_GROUPが使用されます。ALTER INDEXの場合、GROUPキーワードの前に変更操作キーワードを指定します。新しいグループ(アイランド)を作成する場合はADD_GROUPを、グループを削除する場合はDROP_GROUPを指定します。

単に複数のXMLIndex索引を使用するのではなく、1つの索引内で複数のグループを使用する理由を考えてみます。その理由は、XMLIndexがドメイン索引であること、そして特定のデータベース列に対しては特定タイプのドメイン索引を1つしか作成できないことです。

構造グループを定義する(つまり、構造化アイランドに索引を作成する)ための構文は、SQL/XML関数XMLTableを起動するための構文と似ています。リレーショナル列を定義するにはキーワードXMLTableおよびCOLUMNSを使用し、コレクションを処理するにはXMLTableのマルチレベル連鎖を使用します。このような索引を簡単に作成するには、PL/SQL関数DBMS_XMLSTORAGE_MANAGE.getSIDXDefFromViewを使用すれば、索引の作成に必要なXMLTable式を正確に記述できます。

関連項目:

6.3.7.1 XMLIndex構造化コンポーネントでの名前空間とStorage句の使用

構造化コンポーネントを持つXMLIndex索引を作成するとき、使用するXML名前空間と記憶域オプションを指定できます。

例6-21に、XMLIndex索引の作成を示します。この索引には、構造化コンポーネントのみが含まれ(パス表句は含まれない)、XMLNAMESPACES句を使用して名前空間を指定します。索引データを圧縮し、表領域USERTBS1を使用することを指定します。この例では、XML Schemaに基づかないデータを含むバイナリXML表po_binxmlを想定しています。

例6-21に示した(同一の)各TABLESPACE句は、表レベル(po_ptab表およびli_tab表)で適用されます。

一般的に、記憶域オプションは表レベルとパーティション・レベルの両方で指定できます。パーティション・レベルでの指定により、表レベルでの指定がオーバーライドされます。TABLESPACE句は索引レベルで指定することもできるため、その索引に使用されているすべてのパーティションと表に適用されます。TABLESPACEが複数のレベルで指定されている場合、パーティション・レベルにより表レベルがオーバーライドされ、表レベルにより索引レベルがオーバーライドされます。

例6-22では、索引で使用されている各表に同じTABLESPACEを指定します。例6-22に示すように、TABLESPACEを索引レベルで指定することで、この共通点を取り除くことができます。

例6-21 名前空間および記憶域オプションを使用した、構造化コンポーネントを含むXMLIndex

CREATE INDEX po_struct ON po_binxml (OBJECT_VALUE) INDEXTYPE IS XDB.XMLIndex
  PARAMETERS ('XMLTable po_ptab
                 (TABLESPACE "USERTBS1" COMPRESS FOR OLTP)
                  XMLNAMESPACES (DEFAULT ''http://www.example.com/po''),
                 ''/purchaseOrder''
                 COLUMNS orderdate   DATE          PATH ''@orderDate'',
                         id          BINARY_DOUBLE PATH ''@id'',
                         items       XMLType       PATH ''items/item'' VIRTUAL
               XMLTable li_tab
                 (TABLESPACE "USERTBS1" COMPRESS FOR OLTP)
                  XMLNAMESPACES (DEFAULT ''http://www.example.com/po''),
                 ''/item'' PASSING items
                 COLUMNS partnum     VARCHAR2(15)  PATH ''@partNum'',
                         description CLOB          PATH ''productName'',
                         usprice     BINARY_DOUBLE PATH ''USPrice'',
                         shipdat     DATE          PATH ''shipDate''');

例6-22 TABLESPACEを索引レベルで指定した、構造化コンポーネントを含むXMLIndex

CREATE INDEX po_struct ON po_binxml (OBJECT_VALUE) INDEXTYPE IS XDB.XMLIndex
  PARAMETERS ('XMLTable po_ptab,
                  XMLNAMESPACES (DEFAULT ''http://www.example.com/po''),
                 ''/purchaseOrder''
                 COLUMNS orderdate   DATE          PATH ''@orderDate'',
                         id          BINARY_DOUBLE PATH ''@id'',
                         items       XMLType       PATH ''items/item'' VIRTUAL
               XMLTable li_tab,
                  XMLNAMESPACES (DEFAULT ''http://www.example.com/po''),
                 ''/item'' PASSING items
                 COLUMNS partnum     VARCHAR2(15)  PATH ''@partNum'',
                         description CLOB          PATH ''productName'',
                         usprice     BINARY_DOUBLE PATH ''USPrice'',
                         shipdat     DATE          PATH ''shipDate''
               TABLESPACE "USERTBS1" COMPRESS FOR OLTP)');
6.3.7.2 XMLIndex索引への構造化コンポーネントの追加

ALTER INDEXを使用して、既存のXMLIndex索引に構造化コンポーネントを追加できます。

例6-23に、非構造化コンポーネントのみを含むXMLIndex索引を作成する方法を示します。PARAMETERS句でパス・ノードに明示的に名前付けしているため、非構造化コンポーネントが作成されます。

例6-23では、ALTER INDEXを使用して、po_itemという名前の構造化コンポーネント(グループ)を追加します。この構造グループには、キーワードXMLTableで指定された2つのリレーショナル表が含まれます。

最上位の表po_idx_tabには、referencerequestorusernameおよびlineitemの列があります。lineitem列の型はXMLTypeです。この列はコレクションを表しているため、2番目のXMLTable構造体に渡されて、2番目のレベルのリレーショナル表po_index_lineitemを構成します。この表には、列itemnodescriptionpartnoquantityおよびunitpriceが含まれます。

XMLType列にはキーワードVIRTUAL必要です。このキーワードは、XMLType列自体が生成されないことを指定します。つまり、そのデータは、対応するXMLTable表により指定されたリレーショナル列の形式でのみ、XMLIndex索引に格納されます。

1つのXMLTable内に複数のXMLType列を作成することはできません。1つのXMLTable内に複数のXMLType列を入れる場合は、追加のグループを定義する必要があります。

例6-23にも、PARAMETERS句での登録済パラメータ文字列の使用を示します。これはPL/SQLのプロシージャDBMS_XMLINDEX.registerParameterを使用して、myparamという名前のパラメータ文字列を登録します。次にALTER INDEXを使用して、文字列myparamに含まれるように索引パラメータを更新します。

例6-23 XMLIndex索引: 構造化コンポーネントの追加

CREATE INDEX po_xmlindex_ix ON po_binxml (OBJECT_VALUE)
  INDEXTYPE IS XDB.XMLIndex PARAMETERS ('PATH TABLE path_tab');

BEGIN
  DBMS_XMLINDEX.registerParameter(
    'myparam',
    'ADD_GROUP GROUP po_item
       XMLTable po_idx_tab ''/PurchaseOrder''
         COLUMNS reference   VARCHAR2(30)  PATH ''Reference'',
                 requestor   VARCHAR2(30)  PATH ''Requestor'',
                 username    VARCHAR2(30)  PATH ''User'',
                 lineitem    XMLType       PATH ''LineItems/LineItem'' VIRTUAL
       XMLTable po_index_lineitem ''/LineItem'' PASSING lineitem
         COLUMNS itemno      BINARY_DOUBLE PATH ''@ItemNumber'',
                 description VARCHAR2(256) PATH ''Description'',
                 partno      VARCHAR2(14)  PATH ''Part/@Id'',
                 quantity    BINARY_DOUBLE PATH ''Part/@Quantity'',
                 unitprice   BINARY_DOUBLE PATH ''Part/@UnitPrice''');
END;
/

ALTER INDEX po_xmlindex_ix PARAMETERS('PARAM myparam');
6.3.7.3 XMLIndex構造化コンポーネントでの非ブロック・モードによるALTER INDEXの使用

XMLIndex索引の構造化コンポーネントにグループまたは列を追加する際に、ALTER INDEXによるブロックを回避できるため、この索引を使用する問合せでは、待機する必要はありません。

ALTER INDEXを使用して、XMLIndex索引の構造化コンポーネントにグループまたは列を追加する場合、この索引メンテナンス操作では、実表および索引に対して排他DDLロックを取得します。

ALTER INDEX操作が終了するまで、実表はDML操作に対してロックされ、索引を問合せで使用することはできません。つまり、この索引メンテナンス中は、実表に対して問合せやDML操作を実行する別のセッションから索引を使用することはできません。ALTER INDEX操作とそれに附随するロックの期間は、XMLTypeの実列に含まれているデータ量によって異なります。

この問題を回避するには、次の手順を実行します。

  1. 構造化コンポーネントのグループまたは列を作成するALTER INDEX文のPARAMETERS句で、ADD_GROUPまたはADD_COLUMNの前にキーワードNONBLOCKINGを指定します。

    これにより、必要に応じて索引は更新されますが、実表のデータは索引付けされません。実表のデータに依存しないため、実表のサイズに関係なく高速です。

  2. PL/SQLプロシージャDBMS_XMLINDEX.process_pendingを呼び出します。

    このプロシージャでは、キーワードNONBLOCKINGが指定されていないかのように、実表の行に索引付けして索引の表にデータを移入します。ただし、この場合、処理および変更のコミットが行われている間にロックされる行はわずか数行です。他の目的ですでにロックされていた行はスキップされます。これにより、ロック競合が大幅に減少し、一部の行への索引付けを可能にしつつ、同時に、その他の行に対して問合せやDML操作を実行できます。

    プロシージャprocess_pendingが終了すると、次のOUTパラメータを戻します。

    • 索引付けできなかった行の数。この原因は、それらが他の目的でロックされていたか、エラーが発生したためかのいずれかです(この数には、もう1つのOUTパラメータとして戻された数も含みます)。

      これらのロックが解除されたことを確認した後で、プロシージャprocess_pendingをもう一度呼び出して、保留中の行の処理を試みます。

    • エラーが発生したために索引付けできなかった行の数(これはまれなケースです)。

      SYS_AIXSXI_index_number_ERRORTABでエラーの詳細を確認し、問題の原因を解決するための処置を取ります。index_numberとは、索引オブジェクト番号のことです。

  3. すべての行が正常に索引付けされたことをプロシージャprocess_pendingが示すか、解決できない問題が発生して索引付けの操作を完全にキャンセルする判断をユーザーが下すまで、ステップ2を必要な回数繰り返します。

    同じXMLIndex索引に対し、別のALTER INDEX文のPARAMETERS句で、キーワードNONBLOCKING ABORTを指定することにより、索引付けは(ステップ2の前に)いつでもキャンセルできます。

  4. すべての行が正常に索引付けされた場合は、同じXMLIndex索引に対して、別のALTER INDEX文のPARAMETERS句で、キーワードNONBLOCKING COMPLETEを指定します。

例6-24に、これを示します。

SYS_AIXSXI_index_number_ERRORTABがエラーをレポートするように、表SYS_AIXSXI_index_number_PENDINGTABには、索引の有無に関係なく、実表の行ごとに現在のステータスが記録されます。何か他の目的で行がロックされているか、索引付けを試みてエラーが発生したために、まだ索引付けされていない行がある場合があります。後者の場合は、SYS_AIXSXI_index_number_ERRORTABを参照して、エラーの詳細を確認してください。

例6-24 DBMS_XMLINDEX.PROCESS_PENDINGを使用したXMLデータの索引付け

CREATE INDEX po_struct ON po_binxml (OBJECT_VALUE) INDEXTYPE IS XDB.XMLIndex
  PARAMETERS ('XMLTable po_idx_tab
                 ''/PurchaseOrder''
                 COLUMNS reference   VARCHAR2(30)  PATH ''Reference'',
                         requestor   VARCHAR2(30)  PATH ''Requestor'',
                         username    VARCHAR2(30)  PATH ''User'',
                         lineitem    XMLType       PATH ''LineItems/LineItem'' VIRTUAL
               XMLTable po_index_lineitem
                 ''/LineItem'' PASSING lineitem
                 COLUMNS itemno      BINARY_DOUBLE PATH ''@ItemNumber'',
                         description VARCHAR2(256) PATH ''Description'',
                         partno      VARCHAR2(14)  PATH ''Part/@Id'',
                         quantity    BINARY_DOUBLE PATH ''Part/@Quantity'',
                         unitprice   BINARY_DOUBLE PATH ''Part/@UnitPrice''');
 
ALTER INDEX po_struct
  PARAMETERS('NONBLOCKING ADD_GROUP GROUP po_action_group 
              XMLTABLE po_idx_tab
                ''/PurchaseOrder''
                COLUMNS actions       XMLType       PATH  ''Actions/Action'' VIRTUAL
              XMLTABLE po_idx_action
                ''/Action'' PASSING actions
                COLUMNS actioned_by   VARCHAR2(10)  PATH  ''User'',
                        date_actioned TIMESTAMP     PATH  ''Date''');

DECLARE
  num_pending NUMBER := 0;
  num_errored NUMBER := 0;
BEGIN
 DBMS_XMLINDEX.process_pending('oe', 'po_struct', num_pending, num_errored);
 DBMS_OUTPUT.put_line('Number of rows still pending = ' || num_pending);
 DBMS_OUTPUT.put_line('Number of rows with errors   = ' || num_errored);
END;
/
Number of rows still pending = 0
Number of rows with errors   = 0
 
PL/SQL procedure successfully completed.

ALTER INDEX po_struct PARAMETERS('NONBLOCKING COMPLETE');
6.3.7.4 構造化XMLIndexコンポーネントのデータ型の変更

データの一部が構造化XMLIndexコンポーネントの対応する列で使用されているデータ型と一致しないためにエラーが発生する場合は、キーワードMODIFY_COLUMN_TYPEALTER INDEXに渡すことによって、索引を簡単に変更できることがあります。

たとえば、VARCHAR2(30)列にデータを40文字まで収容する必要がある場合は、それをVARCHAR2(40)などに拡張できます。列を削除してから新しい列を追加するよりも、この方が簡単でより効率的です。ただし、ALTER TABLE MODIFY COLUMNと同じ制約が適用されるので、新旧のデータ型が一致している必要があります。

関連項目:

6.3.7.5 XMLIndex構造化コンポーネントの削除

XMLIndex索引に非構造化コンポーネントと構造化コンポーネントの両方が含まれる場合は、ALTER INDEXを使用して構造化コンポーネントを削除できます。これを行うには、構造化コンポーネントを構成するすべての構造グループを削除します。

例6-25に、例6-23で追加された構造化コンポーネントを削除する方法を示します。この場合は、その構造グループpo_itemのみを削除します。

例6-25 XMLIndex構造化コンポーネントの削除

ALTER INDEX po_xmlindex_ix PARAMETERS('DROP_GROUP GROUP po_item');
6.3.7.6 構造化XMLIndexコンポーネントのリレーショナル表への索引付け

XMLIndex索引の構造化コンポーネントに使用する表は通常のリレーショナル表であるため、標準的な任意のリレーショナル索引を使用して、これらの表に索引付けできます。

詳細は、XMLIndex構造化コンポーネントの項を参照してください。例6-26に、これを示します。この例では、例6-23XMLIndex索引に対して、索引コンテンツ表(構造化フラグメント)のreference列にBツリー索引を作成します。

例6-26 XMLIndex索引コンテンツ表に対するBツリー索引の作成

CREATE INDEX idx_tab_ref_ix ON po_idx_tab (reference);

6.3.8 XMLIndexが使用されるかどうかを判別する方法

特定のXMLIndex索引が問合せの解決に使用されたかどうかを把握するには、問合せの実行計画を検証します。

特定のXMLIndex索引を使用できるかどうかは、問合せのコンパイル時にOracle Databaseにより決定されます。つまり、索引に対する問合せにその問合せをリライトできるかどうかによって決まります。

非構造化XMLIndexコンポーネントの場合、問合せ内のXPath式が、XMLIndex索引付けに使用するよう指定したパスのサブセットであることをコンパイル時に断定できない場合、索引の非構造化コンポーネントは使用されません。

たとえば、索引付けの際にパス/PurchaseOrder/LineItems//*が含まれる場合、/PurchaseOrder/LineItems/LineItem/Descriptionを含む問合せでは索引を使用できますが、//Descriptionを含む問合せは索引を使用できません。後者は、/PurchaseOrder/LineItemsの子ではない潜在的なDescription要素と一致し、そのDescription要素がデータに出現するかどうかはコンパイル時に判断できません。

特定のXMLIndex索引が問合せの解決に使用されたかどうかを把握するには、問合せの実行計画を検証します。

  • 索引の非構造化コンポーネントが使用される場合、そのパス表、順序キー、またはパスIDが実行計画において参照されます。実行計画は、ドメイン索引が使用されていることを直接的に示すことはありませんXMLIndex索引を名前で参照することもありません例6-27および例6-29を参照してください。

  • 索引の構造化コンポーネントが使用される場合、その索引コンテンツ表の1つ以上が実行計画において呼び出されます。例6-30および例6-31を参照してください。

例6-27に、例6-10で作成したXMLIndex索引が特定の問合せで使用される様子を示します。ここで示す実行計画のMY_PATH_TABLEへの参照は、XMLIndex索引(例6-10で作成)が問合せで使用されることを示します。同様に、LOCATORORDER_KEY、およびPATHIDの各列への参照も、同じことを示します。

例6-28に示すように、このような実行計画からパス表の名前から、XMLIndex索引の名前を取得できます。(これは例6-11の問合せとほぼ反対のケースです。)

XMLIndexは、SELECTリスト、FROMリスト、および問合せのWHERE句のXPath式で使用でき、SQL/XML関数XMLQueryXMLTableXMLExistsおよびXMLCastにおいて有用です。ファンクション索引(XMLTypeでは非推奨)とは異なり、XMLIndex索引は、文書内のXMLフラグメントからデータを抽出する際に使用できます。

例6-29に、これを示します。

例6-29の問合せの実行計画は、パス表を参照することにより、XMLIndexが使用されることを示します。Oracle内部SQL関数sys_orderkey_depthが使用されることも示します。非構造化コンポーネントを含むXMLIndexを使用するためのガイドラインを参照してください。

例6-30に、例6-23で作成したXMLIndex索引が2つのWHERE句述語を使用する問合せに対して選択されることを示す実行計画を示します。それは例6-46と同じ問合せで、実行計画にも示されているように、同じXML検索索引が使用されています。

非構造化XMLIndexコンポーネントのみが含まれる場合、WHERE句内に2つの異なるパスがあるため、問合せに対してパス表の自己結合が行われます。

例6-30で、パス表名path_tabが存在することは、索引の非構造化コンポーネントが使用されることを示しています。索引コンテンツ表po_idx_tabが存在することは、構造化索引コンポーネントが使用されることを示しています。XML検索索引po_ctx_idxが存在することは、それも使用されることを示しています。

例6-31に、同じXMLIndex索引が、マルチレベルのXMLTable連鎖を使用する問合せに対して取得されることを示す実行計画を示します。非構造化XMLIndexコンポーネントのみが含まれる場合、2つのXMLTableファンクション・コールに2つの異なるパスがあるため、この問合せに対してもパス表の自己結合が行われます。

この実行計画は、リレーショナル索引コンテンツ表po_idx_tabおよびpo_index_lineitemへの直接アクセスを示しています。パス表path_tabへのアクセスはまったくありません

例6-27 XMLIndex非構造化コンポーネントが使用されるかどうかの確認

SET AUTOTRACE ON EXPLAIN

SELECT XMLQuery('/PurchaseOrder/Requestor' PASSING OBJECT_VALUE RETURNING CONTENT) FROM po_binxml
  WHERE XMLExists('/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]' PASSING OBJECT_VALUE);
 
XMLQUERY('/PURCHASEORDER/REQUESTOR'PASSINGOBJECT_VALUERETURNINGCONTENT)
-----------------------------------------------------------------------
<Requestor>Sarah J. Bell</Requestor>
 
1 row selected.
 
 
Execution Plan
. . .
----------------------------------------------------------------------------------------------------------------
| Id  | Operation                       | Name                         | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                |                              |     1 |    24 |    28   (4)| 00:00:01 |
|   1 |  SORT GROUP BY                  |                              |     1 |  3524 |            |          |
|*  2 |   TABLE ACCESS BY INDEX ROWID   | MY_PATH_TABLE                |     2 |  7048 |     3   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN             | SYS67616_PO_XMLINDE_PIKEY_IX |     1 |       |     2   (0)| 00:00:01 |
|   4 |  NESTED LOOPS                   |                              |     1 |    24 |    28   (4)| 00:00:01 |
|   5 |   VIEW                          | VW_SQ_1                      |     1 |    12 |    26   (0)| 00:00:01 |
|   6 |    HASH UNIQUE                  |                              |     1 |  5046 |            |          |
|   7 |     NESTED LOOPS                |                              |     1 |  5046 |    26   (0)| 00:00:01 |
|*  8 |      TABLE ACCESS BY INDEX ROWID| MY_PATH_TABLE                |     1 |  3524 |    24   (0)| 00:00:01 |
|*  9 |       INDEX RANGE SCAN          | SYS67616_PO_XMLINDE_VALUE_IX |    73 |       |     1   (0)| 00:00:01 |
|* 10 |      TABLE ACCESS BY INDEX ROWID| MY_PATH_TABLE                |     1 |  1522 |     2   (0)| 00:00:01 |
|* 11 |       INDEX RANGE SCAN          | SYS67616_PO_XMLINDE_PIKEY_IX |     1 |       |     1   (0)| 00:00:01 |
|  12 |   TABLE ACCESS BY USER ROWID    | PO_BINXML                    |     1 |    12 |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - filter(SYS_XMLI_LOC_ISNODE("SYS_P0"."LOCATOR")=1)
   3 - access("SYS_P0"."RID"=:B1 AND "SYS_P0"."PATHID"=HEXTORAW('76E2') )
   8 - filter("SYS_P4"."VALUE"='SBELL-2002100912333601PDT' AND "SYS_P4"."PATHID"=HEXTORAW('4F8C')  AND
              SYS_XMLI_LOC_ISNODE("SYS_P4"."LOCATOR")=1)
   9 - access(SUBSTRB("VALUE",1,1599)='SBELL-2002100912333601PDT')
  10 - filter(SYS_XMLI_LOC_ISNODE("SYS_P2"."LOCATOR")=1)
  11 - access("SYS_P4"."RID"="SYS_P2"."RID" AND "SYS_P2"."PATHID"=HEXTORAW('4E36')  AND
              "SYS_P2"."ORDER_KEY"<"SYS_P4"."ORDER_KEY")
       filter("SYS_P4"."ORDER_KEY"<SYS_ORDERKEY_MAXCHILD("SYS_P2"."ORDER_KEY") AND
              SYS_ORDERKEY_DEPTH("SYS_P2"."ORDER_KEY")+1=SYS_ORDERKEY_DEPTH("SYS_P4"."ORDER_KEY"))
. . .

例6-28 パス表名からのXMLIndex索引名の取得

SELECT INDEX_NAME FROM USER_XML_INDEXES WHERE PATH_TABLE_NAME = 'MY_PATH_TABLE';
 
INDEX_NAME
------------------------------
PO_XMLINDEX_IX
 
1 row selected.

例6-29 XMLIndexを使用したXMLフラグメントからのデータ抽出

SET AUTOTRACE ON EXPLAIN
 
SELECT li.description, li.itemno
  FROM po_binxml, XMLTable('/PurchaseOrder/LineItems/LineItem'
                           PASSING OBJECT_VALUE
                           COLUMNS "DESCRIPTION" VARCHAR(40) PATH 'Description',
                                   "ITEMNO"      INTEGER     PATH '@ItemNumber') li
  WHERE XMLExists('/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
                  PASSING OBJECT_VALUE);
 
DESCRIPTION                                  ITEMNO
---------------------------------------- ----------
A Night to Remember                               1
The Unbearable Lightness Of Being                 2
Sisters                                           3
 
3 rows selected.

Execution Plan

----------------------------------------------------------------------------------------------------------------
| Id  | Operation                         | Name                         | Rows  | Bytes |Cost (%CPU)| Time    |
----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |                              |     1 |  1546 |   30   (4)|00:00:01 |
|*  1 |  FILTER                           |                              |       |       |           |          |
|*  2 |   TABLE ACCESS BY INDEX ROWID     | MY_PATH_TABLE                |     1 |  3524 |    3   (0)|00:00:01 |
|*  3 |    INDEX RANGE SCAN               | SYS67616_PO_XMLINDE_PIKEY_IX |     1 |       |    2   (0)|00:00:01 |
|*  4 |  FILTER                           |                              |       |       |           |         |
|*  5 |   TABLE ACCESS BY INDEX ROWID     | MY_PATH_TABLE                |     1 |  3524 |    3   (0)|00:00:01 |
|*  6 |    INDEX RANGE SCAN               | SYS67616_PO_XMLINDE_PIKEY_IX |     1 |       |    2   (0)|00:00:01 |
|   7 |  NESTED LOOPS                     |                              |       |       |           |         |
|   8 |   NESTED LOOPS                    |                              |     1 |  1546 |   30   (4)|00:00:01 |
|   9 |    NESTED LOOPS                   |                              |     1 |    24 |   28   (4)|00:00:01 |
|  10 |     VIEW                          | VW_SQ_1                      |     1 |    12 |   26   (0)|00:00:01 |
|  11 |      HASH UNIQUE                  |                              |     1 |  5046 |           |         |
|  12 |       NESTED LOOPS                |                              |     1 |  5046 |   26   (0)|00:00:01 |
|* 13 |        TABLE ACCESS BY INDEX ROWID| MY_PATH_TABLE                |     1 |  3524 |   24   (0)|00:00:01 |
|* 14 |         INDEX RANGE SCAN          | SYS67616_PO_XMLINDE_VALUE_IX |    73 |       |    1   (0)|00:00:01 |
|* 15 |        TABLE ACCESS BY INDEX ROWID| MY_PATH_TABLE                |     1 |  1522 |    2   (0)|00:00:01 |
|* 16 |         INDEX RANGE SCAN          | SYS67616_PO_XMLINDE_PIKEY_IX |     1 |       |    1   (0)|00:00:01 |
|  17 |     TABLE ACCESS BY USER ROWID    | PO_BINXML                    |     1 |    12 |    1   (0)|00:00:01 |
|* 18 |    INDEX RANGE SCAN               | SYS67616_PO_XMLINDE_PIKEY_IX |     1 |       |    1   (0)|00:00:01 |
|* 19 |   TABLE ACCESS BY INDEX ROWID     | MY_PATH_TABLE                |     1 |  1522 |    2   (0)|00:00:01 |
----------------------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - filter(:B1<SYS_ORDERKEY_MAXCHILD(:B2))
   2 - filter(SYS_XMLI_LOC_ISNODE("SYS_P2"."LOCATOR")=1)
   3 - access("SYS_P2"."RID"=:B1 AND "SYS_P2"."PATHID"=HEXTORAW('28EC')  AND "SYS_P2"."ORDER_KEY">:B2 AND
              "SYS_P2"."ORDER_KEY"<SYS_ORDERKEY_MAXCHILD(:B3))
       filter(SYS_ORDERKEY_DEPTH("SYS_P2"."ORDER_KEY")=SYS_ORDERKEY_DEPTH(:B1)+1)
   4 - filter(:B1<SYS_ORDERKEY_MAXCHILD(:B2))
   5 - filter(SYS_XMLI_LOC_ISNODE("SYS_P5"."LOCATOR")=1)
   6 - access("SYS_P5"."RID"=:B1 AND "SYS_P5"."PATHID"=HEXTORAW('60E0')  AND "SYS_P5"."ORDER_KEY">:B2 AND
              "SYS_P5"."ORDER_KEY"<SYS_ORDERKEY_MAXCHILD(:B3))
       filter(SYS_ORDERKEY_DEPTH("SYS_P5"."ORDER_KEY")=SYS_ORDERKEY_DEPTH(:B1)+1)
  13 - filter("SYS_P10"."VALUE"='SBELL-2002100912333601PDT' AND "SYS_P10"."PATHID"=HEXTORAW('4F8C')  AND
              SYS_XMLI_LOC_ISNODE("SYS_P10"."LOCATOR")=1)
  14 - access(SUBSTRB("VALUE",1,1599)='SBELL-2002100912333601PDT')
  15 - filter(SYS_XMLI_LOC_ISNODE("SYS_P8"."LOCATOR")=1)
  16 - access("SYS_P10"."RID"="SYS_P8"."RID" AND "SYS_P8"."PATHID"=HEXTORAW('4E36')  AND
              "SYS_P8"."ORDER_KEY"<"SYS_P10"."ORDER_KEY")
       filter("SYS_P10"."ORDER_KEY"<SYS_ORDERKEY_MAXCHILD("SYS_P8"."ORDER_KEY") AND
              SYS_ORDERKEY_DEPTH("SYS_P8"."ORDER_KEY")+1=SYS_ORDERKEY_DEPTH("SYS_P10"."ORDER_KEY"))
  18 - access("PO_BINXML".ROWID="SYS_ALIAS_4"."RID" AND "SYS_ALIAS_4"."PATHID"=HEXTORAW('3748') )
  19 - filter(SYS_XMLI_LOC_ISNODE("SYS_ALIAS_4"."LOCATOR")=1)
 
Note
-----
   - dynamic sampling used for this statement (level=2)

例6-30 2つの述語を使用する問合せに対する構造化XMLIndexコンポーネントの使用

EXPLAIN PLAN FOR
  SELECT XMLQuery('/PurchaseOrder/LineItems/LineItem'
                  PASSING OBJECT_VALUE RETURNING CONTENT)
    FROM po_binxml
    WHERE XMLExists('/PurchaseOrder/LineItems/LineItem
                     [Description contains text "Picnic"]'
                    PASSING OBJECT_VALUE)
      AND XMLExists('/PurchaseOrder[User="SBELL"]' PASSING OBJECT_VALUE);
 
Explained.
 
----------------------------------------------------------------------------------------------------------------
| Id  | Operation                            | Name                         |Rows|Bytes| Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                     |                              |   1| 2051|     9   (0)| 00:00:01 |
|   1 |  SORT GROUP BY                       |                              |   1| 3524|            |          |
|*  2 |   TABLE ACCESS BY INDEX ROWID BATCHED| PATH_TAB                     |   2| 7048|     3   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN                  | SYS86751_PO_XMLINDE_PIKEY_IX |   1|     |     2   (0)| 00:00:01 |
|   4 |  NESTED LOOPS SEMI                   |                              |   1| 2051|     6   (0)| 00:00:01 |
|   5 |   TABLE ACCESS BY INDEX ROWID        | PO_BINXML                    |   1| 2024|     4   (0)| 00:00:01 |
|*  6 |    DOMAIN INDEX                      | PO_CTX_IDX                   |    |     |     4   (0)| 00:00:01 |
|*  7 |   TABLE ACCESS BY INDEX ROWID BATCHED| PO_IDX_TAB                   |  13|  351|     2   (0)| 00:00:01 |
|*  8 |    INDEX RANGE SCAN                  | SYS86751_86755_OID_IDX       |   1|     |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - filter(SYS_XMLI_LOC_ISNODE("SYS_P1"."LOCATOR")=1)
   3 - access("SYS_P1"."RID"=:B1 AND "SYS_P1"."PATHID"=HEXTORAW('3748') )
   6 - access("CTXSYS"."CONTAINS"(SYS_MAKEXML(0,"XMLDATA"),'<query><textquery grammar="CONTEXT"
              lang="english">{Picnic} INPATH
              (/PurchaseOrder/LineItems/LineItem/Description)</textquery><xquery><offset>0</
              offset></xquery></query>')>0)
   7 - filter("SYS_SXI_0"."USERNAME"='SBELL')
   8 - access("PO_BINXML"."SYS_NC_OID$"="SYS_SXI_0"."OID")
 
Note
-----
   - dynamic sampling used for this statement (level=2)
 
30 rows selected.

例6-31 マルチレベル連鎖を使用する問合せに対する構造化XMLIndexコンポーネントの使用

EXPLAIN PLAN FOR
  SELECT po.reference, li.*
    FROM po_binxml p,
         XMLTable('/PurchaseOrder' PASSING p.OBJECT_VALUE
                  COLUMNS reference   VARCHAR2(30)  PATH 'Reference',
                          lineitem    XMLType       PATH 'LineItems/LineItem') po,
         XMLTable('/LineItem' PASSING po.lineitem
                  COLUMNS itemno      BINARY_DOUBLE PATH '@ItemNumber',
                          description VARCHAR2(256) PATH 'Description',
                          partno      VARCHAR2(14)  PATH 'Part/@Id',
                          quantity    BINARY_DOUBLE PATH 'Part/@Quantity',
                          unitprice   BINARY_DOUBLE PATH 'Part/@UnitPrice') li
    WHERE po.reference = 'SBELL-20021009123335280PDT';
 
-------------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name                   | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                        |    17 | 20366 |     8   (0)| 00:00:01 |
|   1 |  NESTED LOOPS                |                        |       |       |            |          |
|   2 |   NESTED LOOPS               |                        |    17 | 20366 |     8   (0)| 00:00:01 |
|   3 |    NESTED LOOPS              |                        |     1 |   539 |     3   (0)| 00:00:01 |
|*  4 |     TABLE ACCESS FULL        | PO_IDX_TAB             |     1 |   529 |     3   (0)| 00:00:01 |
|*  5 |     INDEX UNIQUE SCAN        | SYS_C007442            |     1 |    10 |     0   (0)| 00:00:01 |
|*  6 |    INDEX RANGE SCAN          | SYS86751_86759_PKY_IDX |    17 |       |     1   (0)| 00:00:01 |
|   7 |   TABLE ACCESS BY INDEX ROWID| PO_INDEX_LINEITEM      |    17 | 11203 |     5   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   4 - filter("SYS_SXI_2"."REFERENCE"='SBELL-20021009123335280PDT')
   5 - access("P"."SYS_NC_OID$"="SYS_SXI_2"."OID")
   6 - access("SYS_SXI_2"."KEY"="SYS_SXI_3"."PKEY")
 
Note
-----
   - dynamic sampling used for this statement
 
25 rows selected.

6.3.9 XMLIndexの使用の無効化

XMLIndexの使用を無効にするには、オプティマイザ・ヒント/*+ NO_XML_QUERY_REWRITE */またはオプティマイザ・ヒント/*+ NO_XMLINDEX_REWRITE */を使用します。

これらの各ヒントにより、すべてのXMLIndex索引の使用が無効になります。NO_XML_QUERY_REWRITEは、XMLIndexの使用を無効にする他に、XQueryの最適化もすべて無効にします(XMLIndexはXPathリライトの一部です)。

例6-32に、これらのオプティマイザ・ヒントの使用方法を示します。

注意:

NO_INDEXオプティマイザ・ヒントは、XMLIndexには適用されません。

関連項目:

XQueryの最適化を詳細に管理できるXQueryプラグマora:no_xmlquery_rewriteおよびora:xmlquery_rewriteの詳細は、「XQueryのオプション機能」を参照してください。

例6-32 オプティマイザ・ヒントを使用したXMLIndexの無効化

SELECT /*+ NO_XMLINDEX_REWRITE */ 
  count(*) FROM po_binxml WHERE XMLExists('$p/*' PASSING OBJECT_VALUE AS "p");

SELECT /*+ NO_XML_QUERY_REWRITE */
  count(*) FROM po_binxml WHERE XMLExists('$p/*' PASSING OBJECT_VALUE AS "p");

6.3.10 XMLIndexパスのサブセット化: 索引付けするパスの指定

問い合せる可能性の高いXPath式がわかっている場合は、XMLIndexの索引付けの焦点を絞り、パフォーマンスを高めることもできます。

非構造化コンポーネントを含むXMLIndex索引は、非常に汎用性が高いという利点があります。索引付けするXPathの位置を指定する必要もなければ、問合せされるXPath式に関する事前の知識も必要ありません。デフォルトでは、非構造化XMLIndexコンポーネント索引では、XMLデータのすべての使用可能なXPath位置に索引が作成されます。

ただし、問い合せる可能性の高いXPath式を認識している場合は、XMLIndexの索引付けの焦点を絞り、パフォーマンスを高めることもできます。索引付けされたノードが少ないほど、索引付けに必要な領域も削減されるため、DML操作中の索引のメンテナンスが向上します。索引付けされたノードの数が少ないほどDDLのパフォーマンスが向上し、パス表が小さいほど問合せのパフォーマンスも向上します。

索引付けされるXMLフラグメントに対応する一連のXPath式(パス)をプルーニングし、可能なすべてのパスのサブセットを指定することで、索引付けの焦点を絞れます。これを行うには、他に2通りの方法があります。

  • 除外: 可能なすべてのXPath式を含めるというデフォルト動作を実行した後に、索引付けに不要なものを除外します。

  • 包含: 索引付けに使用する空白のXPath式の包含セットにパスを追加します。

CREATE INDEXを使用してXMLIndex索引を作成するとき、またはALTER INDEXを使用して索引を修正するときに、パスのサブセット化を指定できます。いずれの場合でも、文のPARAMETERS句のPATHSパラメータで、サブセット化情報を提供します。除外の場合は、キーワードEXCLUDEを使用します。包含の場合は、ALTER INDEXのときはキーワードINCLUDEを使用し、CREATE INDEXのときはキーワードを使用しません(含めるパスをリストします)。また、PATHSパラメータによってターゲット化されるノードに対し、名前空間マッピングも指定できます。

ALTER INDEXの場合、キーワードINCLUDEまたはEXCLUDEの後にキーワードADDまたはREMOVEを付加すると、キーワードの後に続くパスのリストを包含リストや除外リストに追加するか削除するかを指定できます。たとえば、この文では、索引付けから除外するパスのリストにパス/PurchaseOrder/Referenceを追加します。

ALTER INDEX po_xmlindex_ix REBUILD
  PARAMETERS ('PATHS (EXCLUDE ADD (/PurchaseOrder/Reference))');

すべてのパスが含まれるようにXMLIndex索引を変更するには、キーワードINDEX_ALL_PATHSを使用します。alter_index_paths_clause ::=を参照してください。

注意:

構造化および非構造化コンポーネントの両方を持つXMLIndex索引を作成した場合、デフォルトで、構造化コンポーネント内で索引付けされているノードはすべて、非構造化コンポーネント内でも索引付けされます。つまり、非構造化コンポーネントから自動的に除外されません。非構造化XMLIndexの索引付けを適用しないようにするには、パスのサブセット化を明示的に使用してそれらを除外する必要があります。

6.3.10.1 XMLIndexパスのサブセット化の例

XPath式のサブセットに対し、XMLIndex索引を定義する例をいくつか示します。

例6-33 CREATE INDEXによるXMLIndexパスのサブセット化

CREATE INDEX po_xmlindex_ix ON po_binxml (OBJECT_VALUE) INDEXTYPE IS XDB.XMLIndex
  PARAMETERS ('PATHS (INCLUDE (/PurchaseOrder/LineItems//* 
                               /PurchaseOrder/Reference))');

この文では、次に示すように、最上位要素であるPurchaseOrderおよびその子に対してのみ索引付けする索引を作成します。

  • すべてのLineItems要素およびその子孫

  • すべてのReference要素

索引に使用される一連の空白のパスに対し、指定のパスを含めていきます。

例6-34 ALTER INDEXによるXMLIndexパスのサブセット化

ALTER INDEX po_xmlindex_ix REBUILD
  PARAMETERS ('PATHS (INCLUDE ADD (/PurchaseOrder/Requestor 
                                   /PurchaseOrder/Actions/Action//*))');

この文では、索引付けに使用されたパスに対し、2つのパスを追加します。これらのパスは、Requestor要素と、Action要素の子孫(およびその祖先)に対して索引付けします。

例6-35 名前空間接頭辞を使用したXMLIndexパスのサブセット化

XMLIndex索引付けに使用されるXPath式で名前空間接頭辞が使用される場合、NAMESPACE MAPPING句をPATHSリストで使用して接頭辞を指定できます。次はその例です。

CREATE INDEX po_xmlindex_ix ON po_binxml (OBJECT_VALUE) INDEXTYPE IS XDB.XMLIndex
  PARAMETERS ('PATHS (INCLUDE (/PurchaseOrder/LineItems//*   /PurchaseOrder/ipo:Reference)
                     NAMESPACE MAPPING (xmlns="http://xmlns.oracle.com"
                                        xmlns:ipo="http://xmlns.oracle.com/ipo"))');
6.3.10.2 XMLIndexパスのサブセット化のルール

XMLIndexパスのサブセット化に適用されるルールについて説明します。

  • パスはchild軸およびdescendant軸のみを参照し、さらに、要素ノードおよび属性ノード、またはその名前(ワイルドカードを使用可能)のみをテストする必要があります。特に、パスには述語を含めないでください。

  • パス除外とパス包含を一度に指定できません。いずれかの方法を指定する必要があります。

  • パス除外(包含)によって索引が作成された場合は、パス除外(包含)によってのみ修正が可能です。索引の修正は、パスのサブセット化をさらに制限するか、さらに拡張するかのいずれかです。たとえば、特定のパスを含める索引を作成した後に、特定のパスを除外するよう修正することはできません。

6.3.11 非構造化コンポーネントを含むXMLIndexを使用するためのガイドライン

非構造化コンポーネントを含むXMLIndexを使用する際に役立つ複数のガイドラインがあります。

これらのガイドラインは、ここで説明する2つの方法によって同じ結果セットが戻される場合にのみ該当します。

  • 祖先要素の接頭辞として//を付加しないでください。たとえば、同じ結果セットを戻す場合、/a/b//cではなく//cを使用します。

  • 祖先要素の接頭辞として/*を付加しないでください。たとえば、同じ結果セットを返す場合、/a/*/*ではなく/*/*/*を使用します。

  • WHERE句では、XMLQueryXMLCastではなく、XMLExistsを使用します。これにより最適化が可能になり、パス表VALUE列に対して副問合せが実際に起動されます。たとえば、次のように記述します。

    SELECT count(*) FROM purchaseorder p 
      WHERE 
        XMLExists('$p/PurchaseOrder/LineItems/LineItem/Part[@Id="715515011020"]'
                      PASSING OBJECT_VALUE AS "p");
    

    次のように記述しないでください。

    SELECT count(*) FROM purchaseorder p
      WHERE XMLCast(XMLQuery('$p/PurchaseOrder/LineItems/LineItem/Part/@Id'
                             PASSING OBJECT_VALUE AS "p" RETURNING CONTENT)
                    AS VARCHAR2(14))
            = "715515011020";
    
  • 可能な場合、SELECT句では、count(XMLCast(XMLQuery(...))ではなくcount(*)を使用します。たとえば、発注書のLineItem要素にDescriptionの子が1つしかないことがわかっている場合は、次のように記述します。

    SELECT count(*) FROM po_binxml, XMLTable('//LineItem' PASSING OBJECT_VALUE);
    

    次のように記述しないでください。

    SELECT count(li.value)
     FROM po_binxml p, XMLTable('//LineItem' PASSING p.OBJECT_VALUE
                                COLUMNS value VARCHAR2(30) PATH 'Description') li;
    
  • 問合せのFROMリストで使用されるXPath式の数は、なるべく少なくしてください。たとえば、次のように記述します。

    SELECT li.description
      FROM po_binxml p,
           XMLTable('PurchaseOrder/LineItems/LineItem' PASSING p.OBJECT_VALUE
                    COLUMNS description VARCHAR2(256) PATH 'Description') li;
    

    次のように記述しないでください。

    SELECT li.description
      FROM po_binxml p,
           XMLTable('PurchaseOrder/LineItems' PASSING p.OBJECT_VALUE) ls,
           XMLTable('LineItems/LineItem'      PASSING ls.OBJECT_VALUE
                    COLUMNS description VARCHAR2(256) PATH 'Description') li;
    
  • 仮想表(XMLTable SQL/XML関数などで作成)の内部をドリルダウンするために、問合せでXPath式を使用する場合は、sys_orderkey_depth Oracle SQL関数を使用してパス表の順序キーの2次索引を作成します。このような問合せを次に例示します。選択により仮想的な明細項目表li内のDescription要素にナビゲートします。

    SELECT li.description
      FROM po_binxml p,
           XMLTable('PurchaseOrder/LineItems/LineItem' PASSING p.OBJECT_VALUE
                    COLUMNS description VARCHAR2(256) PATH 'Description') li;
    

    このような問合せはsys_orderkey_depth関数によって評価されます。この関数は、order-key値の深度を戻します。順序索引は2列を使用するため、必要となる索引は、ORDER_KEY列およびRID列、およびORDER_KEY値に対して適用されたsys_orderkey_depth関数のコンポジット索引です。例:

    CREATE INDEX depth_ix ON my_path_table
      (RID, sys_orderkey_depth(ORDER_KEY), ORDER_KEY);

    関連項目:

    sys_orderkey_depthの使用例は、例6-29を参照してください。

6.3.12 構造化コンポーネントを含むXMLIndexの使用のガイドライン

構造化コンポーネントを含むXMLIndexを使用する際に役立つ複数のガイドラインがあります。

  • 構造化コンポーネントを含むXMLIndexを使用して、リレーショナル列としてXMLデータを投影および索引付けします。ファンクション索引は使用しないでください。XMLとの使用は非推奨です。XMLTypeに対するファンクション索引の非推奨化を参照してください。

  • 構造化コンポーネントが含まれるXMLIndex索引と問合せの間のデータ型の対応の確認。XMLIndex構造化コンポーネントのデータ型に関する考慮事項を参照してください。

  • XMLTypeデータに関してリレーショナル・ビューを作成する場合(SQL関数XMLTableなどを使用して)、同じリレーショナル列をターゲットとする、構造化されたコンポーネントを持つXMLIndex索引を作成することも考慮してください。XMLデータのリレーショナル・ビューを参照してください。

  • フラグメント抽出と値のフィルタリング(検索)の両方に単一のXQuery式を使用するかわりに、SELECT句でSQL/XML関数XMLQueryを使用し、WHERE句のフラグメントおよびXMLExistsを抽出して値をフィルタリングします。

    こうすることで、Oracle XML DBがフラグメント抽出の機能的に、あるいはストリーミング評価を使用して評価できます。値のフィルタリングの場合、こうするとOracle XML DBが適切な構造のコンポーネントを持つXMLIndex索引を取得できます。

  • 問合せの結果の順序を設定するには、SQLのORDER BY句とSQL/XML関数XMLTableを使用します。XQueryのorder by句は使用しないでください。構造化されたコンポーネントを含むXMLIndex索引を使用する場合は、特に使用を避けてください。

6.3.13 XMLIndexのパーティション化および並列度

レンジ・パーティション化、リスト・パーティション化、またはハッシュ・パーティション化を使用して、XMLType表や、XMLType列が含まれる表をパーティション化する場合、その表にXMLIndex索引を作成することもできます。オプションで、索引の作成とメンテナンスが並列で実行されるようにできます。

索引作成とメンテナンスを確実に並列化するには、XMLIndex索引を作成または変更するとき、PARALLEL句を(オプションで)使用します。

XMLIndex索引を作成するときにキーワードLOCALを使用すると、索引とその記憶域表すべてが、実表に関連してローカルに同一レベル・パーティション化されます。

キーワードLOCALを使用しない場合は、パーティション化された表にXMLIndex索引を作成できません。また、コンポジット・パーティション化した表には、XMLIndex索引を作成できません。

PARALLEL句を使用しており、実表がパーティション化されていたり、実表で並列度が有効になっている場合は、これによりDML操作(INSERTUPDATEDELETE)と索引DDL操作(CREATEALTERREBUILD)の両方のパフォーマンスを向上させることができます。

索引に並列度を指定すると、問合せサーバー・プロセスそれぞれに個別に記憶域パラメータが適用されるため、記憶域の消費も多くなります。たとえば、INITIAL値が5M、並列度が12で作成された索引は、作成時に少なくとも60Mの記憶域を消費します。

CREATE INDEXおよびALTER INDEXのPARALLEL句の構文は、他のドメイン索引のものと同じです。

{ NOPARALLEL | PARALLEL [ integer ] }

例6-36では、並列度10でXMLIndex索引を作成します。実表がパーティション化されている場合、この索引は同一レベル・パーティション化されます。

例6-36では、パス表と2次索引は、XMLIndex索引そのものと同じ並列度(10)を継承して作成されます。パス表と2次索引に対して個別のPARALLEL句を使用し、異なる並列度を設定することも可能です。例6-37に、これを示します。ここでも、キーワードLOCALにより、実表がパーティション化されている場合、この索引は同一レベル・パーティション化されます。

例6-37ではNOPARALLELが指定されているため、XMLIndex索引そのものが連続して作成されます。2次索引po_pikey_ixも連続で移入されます。これは、2次索引に対して明示的に並列度が指定されておらず、XMLIndex索引から並列度が継承されるためです。パス表そのものは並列度を10として作成され2次索引値の列po_value_ixは、明示的な並列度指定を反映し、並列度5として移入されます。

XMLIndex索引、パス表、またはその2次索引に対して指定した並列度は、後続のDML操作および問合せにおいて使用されます。

XMLIndexの並列度を指定できる位置は、PARAMETERS句のカッコ付きの式の中とその後の2箇所です。

関連項目:

CREATE INDEXのPARALLEL句の詳細は、Oracle Database SQL言語リファレンスを参照してください。

例6-36 XMLIndex索引の並列的な作成

CREATE INDEX po_xmlindex_ix ON sale_info (sale_po_clob) INDEXTYPE IS XDB.XMLIndex 
  LOCAL PARALLEL 10;

例6-37 XMLIndexの内部オブジェクトに対する、異なるPARALLEL度の使用

CREATE INDEX po_xmlindex_ix ON sale_info (sale_po_clob) INDEXTYPE IS XDB.XMLIndex 
  LOCAL NOPARALLEL PARAMETERS ('PATH TABLE po_path_table (PARALLEL 10)
                                PIKEY INDEX po_pikey_ix
                                VALUE INDEX po_value_ix (PARALLEL 5)');

6.3.14 XMLIndex索引の非同期(遅延)メンテナンス

非構造化コンポーネントのみを含むXMLIndex索引メンテナンスのコストを遅延して、コミット時やデータベースの負荷が軽減されているときにのみ、メンテナンスを実行できます。これにより、DMLパフォーマンスを向上させることができ、索引の同期化時に非同期索引行のバルク・ロードを有効にできます。

この機能は、非構造化コンポーネントのみが含まれるXMLIndex索引に適用されます。構造化コンポーネントが含まれるXMLIndex索引に非同期メンテナンスを指定すると(非構造化コンポーネントも含まれている場合でも)、エラーが発生します。

デフォルトでは、XMLIndex索引はDML操作のたびに更新(メンテナンス)されますので、実表と常に同期化されます。状況によっては、このようなことは必要なく、従来の索引の使用が許可される場合があります。そのような場合、索引メンテナンスのコストを遅延するよう決定し、コミット時のみまたはデータベースの負荷が軽減されているある時期に実行できます。これにより、DMLのパフォーマンスを向上させることができます。また、索引の同期化を行う際に、非同期索引行のバルク・ロードを有効にすると、索引メンテナンスのパフォーマンスを向上させることができます。

DML操作では従来の索引を使用しても、パフォーマンス以外には影響がありません。ただし、問合せ結果に影響を与えることもあります。問合せ時に索引が最新の状態でない場合は、問合せ結果も最新でない可能性があります。実表の1列のみがXMLTypeデータ型であったとしても、その表のすべての問合せには、XMLIndex列のXMLIndex索引の最終同期時のデータベース・データが反映されます。

CREATE INDEX文またはALTER INDEX文のPARAMETERS句を使用し、索引メンテナンスの遅延を指定できます。

XMLIndex索引の同期化を遅延しても、次のデータベース操作により、索引が自動的に同期化されるので注意が必要です。

  • 索引に対するDDL操作: ALTER INDEXまたは2次索引の作成

  • 実表に対するDDL操作: ALTER TABLEまたは他の索引の作成

表6-7に、同期化オプションと、オプションの指定に使用されるASYNC句の構文をまとめます。ASYNC句は、CREATE INDEXPARAMETERS句またはXMLIndexALTER INDEX文で使用されます。

表6-7 索引の同期化

同期化するタイミング ASYNC句の構文

常時

ASYNC (SYNC ALWAYS)

これはデフォルトの動作です。前のASYNC指定を無効にするため、明示的に指定できます。

コミット時

ASYNC(SYNC ON COMMIT)

定期的

ASYNC (SYNC EVERY "repeat_interval")

repeat_intervalは、DBMS_SCHEDULERのカレンダ構文と同じです

EVERYを使用するには、CREATE JOB権限が必要です。

手動、オン・デマンド

ASYNC (SYNC MANUAL)

PL/SQLプロシージャDBMS_XMLINDEX.syncIndexを使用すると、索引を手動で同期化できます。

ASYNC構文のオプションのパラメータであるSTALEは、将来に備えて用意されているものであり、明示的に指定する必要はありません。ALWAYSが使用されていれば、値は常にFALSEになります。それ以外の場合の値はTRUEです。このルールに反して明示的なSTALE値を指定すると、エラーが発生します。

例6-38では、明日から毎週月曜日の午後3時に同期化されるXMLIndex索引を作成します。

例6-39では、例6-38で作成された索引を手動で同期化します。

XMLIndex索引の同期化が遅延されると、索引に対する最終同期化以降、実表に対して加えられたすべてのDML変更(挿入、更新、削除)は、DML操作当たり1行ずつ、保留中の表に記録されます。この表の名前は、静的なパブリック・ビューUSER_XML_INDEXESALL_XML_INDEXES、およびDBA_XML_INDEXESPEND_TABLE_NAME列の値です。

この表を検証すると、指定のXMLIndex索引を同期化させる最適な時期を決定できます。保留中の表の行数が多くなると、同期化が必要な索引も多くなります。

保留中の表のサイズが大きい場合、syncIndexのコール時にパラメータREINDEXTRUEに設定すると、例6-39に示すようにパフォーマンスを向上できます。REINDEXTRUEの場合は、すべての2次索引が削除され、保留中の表データを一括ロードした後に再作成されます。

関連項目:

例6-38 XMLIndexに対する遅延同期の指定

CREATE INDEX po_xmlindex_ix ON po_binxml (OBJECT_VALUE) INDEXTYPE IS XDB.XMLIndex
  PARAMETERS ('ASYNC (SYNC EVERY "FREQ=HOURLY; INTERVAL = 1")');

例6-39 SYNCINDEXを使用したXMLIndex索引の手動同期化

EXEC DBMS_XMLINDEX.syncIndex('OE', 'PO_XMLINDEX_IX', REINDEX => TRUE);
6.3.14.1 エラーORA-08181が発生した場合のXMLIndex索引の同期化

問合せを行うとエラーORA-08181が発生する場合は、問合せのXMLType実表に対して、非構造化コンポーネントを含むXMLIndex索引が作成されているかどうかを確認してください。その場合は、DBMS_XMLINDEX.syncIndexを使用して、XMLIndex索引を手動で同期化します。

これは、エラーORA-08181が次の状況で発生した場合にのみ適用されます。

  1. プラガブル・データベースPDB1で、XMLType表または列XTABCOLを作成し、非構造化コンポーネントが含まれるXMLIndex索引を使用して索引付けを行った。
  2. PDB1をコンテナ・データベースに接続している。
  3. PDB1を新しいプラガブル・データベースPDB2にクローニングした。
  4. PDB2で問合せXTABCOLを実行すると、エラーORA-08181が発生する。

同期化しても引き続きエラーが発生する場合は、別の原因を探します。エラーORA-08181は様々な状況で発生する可能性のある一般的なエラーで、これは原因の1つにすぎません。

6.3.15 コストベース・オプティマイザに対するXMLIndexオブジェクトの統計の収集

Oracle Databaseのコストベース・オプティマイザにより、使用される索引(ある場合)も含め、所定の問合せをどのように評価すると最も費用効率が高いかが決定します。これを正確に実行するには、様々なデータベース・オブジェクトの統計を収集する必要があります。

注意:

次は、パッケージDBMS_STATS内のプロシージャのみに適用され、ANALYZE INDEXには適用されません。

XMLIndexについては、通常はXMLIndex索引が定義されている実表に関する統計のみ収集する必要があります(DBMS_STATS.gather_table_statsプロシージャなどを使用)。これにより、XMLIndex索引自体、パス表とその2次索引、および構造化コンポーネント・コンテンツ表とその2次索引に関する統計が自動的に収集されます。

実表の統計を削除すると(DBMS_STATS.delete_table_statsプロシージャを使用)、他のオブジェクトに関する統計も削除されます。同様に、XMLIndex索引に関する統計を収集すると(DBMS_STATS.gather_index_statsプロシージャを使用)、パス表とその2次索引、および構造化コンポーネント・コンテンツ表とその2次索引に関する統計も収集されます。

例6-40では、実表po_binxmlに関する統計を収集します。XMLIndex索引、パス表、および2次パス表索引に関する統計が自動的に収集されます。

関連項目:

XMLIndex索引の統計情報を記録するデータベース・ビューの詳細は、XMLIndexに関連するデータ・ディクショナリの静的なパブリック・ビューを参照してください。

例6-40 XMLIndexオブジェクトに関する統計の自動収集

CALL DBMS_STATS.gather_table_stats(USER, 'PO_BINXML', ESTIMATE_PERCENT => NULL);

6.3.16 XMLIndexに関連するデータ・ディクショナリの静的なパブリック・ビュー

標準的なデータベース索引に関する情報は、静的なパブリック・ビューUSER_INDEXESALL_INDEXES、およびDBA_INDEXESにあります。XMLIndex索引に関する同様の情報も、静的なパブリック・ビューUSER_XML_INDEXESALL_XML_INDEXES、およびDBA_XML_INDEXESにあります。

表6-8で、これらの各ビューの列について説明します。

表6-8 XMLIndexの静的なパブリック・ビュー

列名 説明

ASYNC

VARCHAR2

非同期索引の更新の仕様です。XMLIndex索引の非同期(遅延)メンテナンスを参照してください。

EX_OR_INCLUDE

VARCHAR2

パスのサブセット化:

  • FULLY_IX: 索引でパスのサブセット化を使用しません。

  • EXCLUDE: 索引で除外のサブセット化のみを使用します。

  • INCLUDE: 索引で包含のサブセット化のみを使用します。

INDEX_NAME

VARCHAR2

XMLIndex索引の名前です。

INDEX_OWNER

VARCHAR2

索引の所有者です。USER_XML_INDEXESには使用されません。

INDEX_TYPE

VARCHAR2

索引のコンポーネントのタイプは、STRUCTUREDUNSTRUCTUREDまたはSTRUCTURED AND UNSTRUCTUREDで構成されます。

PARAMETERS

XMLType

索引の作成に使用されたPARAMETERS句の情報。

非構造化XMLIndexコンポーネントが存在する場合、PARAMETERS句には、パスのサブセット化を定義する一連のXPathパスと、同期化されるスケジューラ・ジョブの名前を含めることができます。

構造化コンポーネントが存在する場合、PARAMETERS句には、XMLTable(列を定義するXQuery式を含む)で提供される構造グループの名前と表定義が含まれます。

PATH_TABLE_NAME

VARCHAR2

XMLIndexパス表の名前です。

PEND_TABLE_NAME

VARCHAR2

最後に行われた索引の同期以降の、実表のDML操作を記録する表の名前です。XMLIndex索引の非同期(遅延)メンテナンスを参照してください。

TABLE_NAME

VARCHAR2

索引が定義されている実表の名前です。

TABLE_OWNER

VARCHAR2

索引が定義されている実表の所有者です。

これらのビューでは、XMLIndex索引に関する情報が提供されますが、XMLIndex索引で収集される統計に関する情報を提供する静的データ・ディクショナリ・ビューはありません。この統計情報は、次のビュー間で配信されます。

  • USER_INDEXESALL_INDEXESDBA_INDEXES: 列LAST_ANALYZEDでは、XMLIndex索引の最終分析日が提供されます。

  • USER_TAB_STATISTICSALL_TAB_STATISTICSDBA_TAB_STATISTICS: 列TABLE_NAMEでは、XMLIndex索引の構造化コンポーネントおよび非構造化コンポーネントの情報が提供されます。構造化コンポーネントまたは非構造化コンポーネントの情報については、パス表またはXMLTable表の名前をTABLE_NAMEとしてそれぞれ使用して問い合せます。

  • USER_IND_STATISTICSALL_IND_STATISTICSDBA_IND_STATISTICS: 列INDEX_NAMEでは、XMLIndex索引の2次索引のそれぞれの情報が提供されます。指定された2次索引に関する情報については、その2次索引の名前をINDEX_NAMEとして使用して問い合せます。

6.3.17 CREATE INDEXおよびALTER INDEXのPARAMETERS句

XMLIndex索引の作成または変更では、多くの場合、SQL文CREATE INDEXまたはALTER INDEXPARAMETERS句が使用されます。これを使用して、詳細に索引特性を指定できます。

PARAMETERS句の1000文字の制限を回避するために、パッケージDBMS_XMLINDEX内のPL/SQLプロシージャregisterParameterおよびmodifyParameterを使用できます。

関連項目:

6.3.17.1 XMLIndexの登録済パラメータ句の使用

CREATE INDEXまたはALTER INDEX文のPARAMETERS句に使用する文字列値には、1000文字の制限があります。この制限を回避するには、パッケージDBMS_XMLINDEX内のPL/SQLプロシージャregisterParameterおよびmodifyParameterを使用できます。

これらのプロシージャごとに、(長さ制限のない)パラメータの文字列と、その文字列の登録に使用する識別子を指定します。次に索引PARAMETERS句で、リテラル文字列ではなく、キーワードPARAMで始まる識別子を指定します。

識別子は、CREATE INDEXまたはALTER INDEX文で使用する前に、登録しておく必要があります。

6.3.17.2 CREATE INDEXおよびALTER INDEXのPARAMETERS句の構文

CREATE INDEXおよびALTER INDEXPARAMETERS句の構文は、定義されています。

XMLIndex_parameters_clause ::=

XMLIndex_parameters ::=

XMLIndex_parameter_clause ::=

unstructured_clause ::=

create_index_paths_clause ::=

alter_index_paths_clause ::=

namespace_mapping_clause ::=

path_table_clause ::=

pikey_clause ::=

path_id_clause ::=

order_key_clause ::=

value_clause ::=

drop_path_table_clause ::=

parallel_clause ::=

structured_clause ::=

async_clause ::=

groups_clause ::=

group_clause ::=

XMLIndex_xmltable_clause ::=

構文要素XML_namespaces_clauseおよびXQuery_stringは、SQL/XML関数XMLTableの場合と同じです。

column_clause ::=

構文要素column_clauseは、SQL/XML関数XMLTableXML_table_columnと似ていますが同じではありません。

alter_index_group_clause ::=

add_column_clause :==

add_column_options :==

構文要素XML_namespaces_clauseは、SQL/XML関数XMLTableの場合と同じです。Oracle XML DBのXMLTABLE SQL/XML関数を参照してください。

drop_column_clause :==

drop_column_options :==

modify_column_type_clause :==

modify_column_type_options :==

6.3.17.3 XMLIndex_parameters_clauseの使用

XMLIndex索引を作成するとき、XMLIndex_parameters_clauseがなければ、新しい索引には非構造化コンポーネントのみが含まれます。XMLIndex_parameters_clauseがあってもPARAMETERS引数が空('')の場合、結果は同じであり、索引には非構造化コンポーネントのみが含められます。

関連項目:

6.3.17.4 XMLIndex_parameterの使用

XMLIndex_parametersを使用する場合は、特定の考慮事項が適用されます。

  • XMLIndex_parametersでは、XMLIndex_parameter_clauseを1種類当たり最大1回しか使用できません。たとえば、PATHS句を最大で1回、path_table_clauseを最大で1回などです。

  • XMLIndex索引を作成するとき、structured_clauseがなければ、新しい索引には非構造化コンポーネントのみが含められます。structured_clauseが存在すれば、新しい索引には構造化コンポーネントのみが含められます。

6.3.17.5 PATHS句の使用

PATHS句を使用する場合は、特定の考慮事項が適用されます。

  • CREATE INDEX文では、PATHS句を最大で1回使用できます。つまり、create_index_paths_clauseの前に、PATHSを最大で1回使用できます。

  • create_index_paths_clause句はCREATE INDEXでのみ、また、alter_index_paths_clause句はALTER INDEXでのみ使用されます。

6.3.17.6 create_index_paths_clauseおよびalter_index_paths_clauseの使用

create_index_paths_clauseおよびalter_index_paths_clauseを使用する場合は、特定の考慮事項が適用されます。

  • INDEX_ALL_PATHSキーワードは、すべてのパスが含まれた状態で索引を再構築します。このキーワードは、alter_index_paths_clauseでのみ使用でき、create_index_paths_clauseでは使用できません。

  • 索引に対するパスの明示的なリストには、ワイルドカードおよび//を使用できます。

  • XPaths_listは1つ以上のXpaths式で構成されるリストです。それぞれのリストには、child軸、descendant軸、名前テスト、およびワイルドカード(*)構造のみが含まれます。

  • create_index_paths_clauseからXPaths_listが省略されていると、すべてのパスが索引付けされます。

  • XPaths_listのXPath式で使用される一意の名前空間接頭辞に対し、対応する名前空間情報を提供するには、標準的なXML名前空間宣言が必要です。

  • 索引を削除した後で必要に応じて作成しなおすと、構文に直接反映されない方法で索引を変更できます。たとえば、パスを含めることで定義される索引を、パスを除外することで定義される索引に変更する場合は、索引を削除した後で、EXCLUDEを使用して作成しなおします。

6.3.17.7 pikey_clause、path_id_clauseおよびorder_key_clauseの使用

pikey_clausepath_id_clauseおよびorder_key_clauseの各句は、構文的にそれぞれ省略可能です。pikey索引は、pikey_clauseを指定しない場合でも作成されます。パスID索引または順序キー索引を作成するには、path_id_clauseまたはorder_key_clauseをそれぞれ指定する必要があります。

6.3.17.8 value_clauseの使用

value_clauseを使用する場合は、特定の考慮事項が適用されます。

  • VALUE列は、VARCHAR2(4000)として作成されています。

  • value_clause句がキーワードVALUEでのみ構成される場合は、通常のデフォルト属性によって値索引が作成されます。

  • path_id_clause句がキーワードPATH IDでのみ構成される場合は、通常のデフォルト属性によってパスID索引が作成されます。

  • order_key_clause句がキーワードORDER KEYでのみ構成される場合は、通常のデフォルト属性によって順序キー索引が作成されます。

6.3.17.9 async_clauseの使用

ASYNC句を使用する場合は、特定の考慮事項が適用されます。

  • この機能は、非構造化コンポーネントのみが含まれるXMLIndex索引のみで使用します。構造化コンポーネントが含まれるXMLIndex索引にASYNC句を指定すると、エラーが発生します。

  • ALWAYSとは、各DML文に対して自動同期が行われることを意味します。

  • MANUALとは、自動同期が行われないことを意味します。DBMS_XMLINDEX.syncIndexを使用して、索引を手動同期させる必要があります。

  • EVERY repeat_intervalとは、repeat_intervalの間隔で索引を自動同期させることを意味します。repeat_intervalの構文は、PL/SQLパッケージDBMS_SCHEDULERと同じで、二重引用符(")で囲む必要があります。EVERYを使用するには、CREATE JOB権限が必要です。

  • ON COMMITとは、コミット操作の直後に索引を同期させることを意味します。コミットは、同期が完了するまでは戻されません。同期は個別の処理として実行されるため、データがコミットされてから、索引の変更がコミットされるまで短い間隔が生じることがあります。

  • STALEはオプションです。値がTRUEの場合は、問合せ結果が失効している可能性があります。値がFALSEの場合は、問合せ結果は常に最新です。デフォルト値と、明示的に指定可能な唯一の値は次のとおりです。

    • ALWAYSの場合、STALEFALSEです。

    • ALWAYS以外のASYNCオプションの場合、STALETRUEです。

6.3.17.10 groups_clauseおよびalter_index_group_clauseの使用

groups_clause句は、CREATE INDEX (alter_index_group_clause句のADD GROUPの後)でのみ使用されます。alter_index_group_clause句は、ALTER INDEXでのみ使用されます。

6.3.17.11 XMLIndex_xmltable_clauseの使用

XMLIndex_xmltable_clauseを使用する場合は、特定の考慮事項が適用されます。

  • XMLIndex_xmltable_clause内のXQuery_string式では、XQuery関数ora:view (サポート対象外)、fn:docまたはfn:collectionを使用できません。

  • 特定のXMLIndex_xmltable_clauseにデータ型XMLTypecolumn_clauseが複数含まれる場合、Oracle XML DBでエラーが発生します。このような2つの仮想列を定義した場合と同じ結果にするには、個別にgroup_clauseを追加する必要があります。

  • XMLIndex_xmltable_clauseではPASSING句はオプションです。この句が存在しない場合、次のようにXMLType列が暗黙的に渡されます。

    • パラメータ句の最初のXMLIndex_xmltable_clauseでは、索引付けされるXMLType列が暗黙的に渡されます。(XMLType表に索引を作成する場合、疑似列OBJECT_VALUEが渡されます。)

    • それ以降の各XMLIndex_xmltable_clauseについては、その前のXMLIndex_xmltable_clauseVIRTUAL XMLType列が暗黙的に渡されます。

6.3.17.12 column_clauseの使用

column_clauseを使用する場合は、特定の考慮事項が適用されます。

XMLIndex索引でXMLTableのマルチレベル連鎖を使用する場合、あるレベルのXMLTable表は、その前のレベルのXMLType列に対応します。構文の説明で、キーワードVIRTUALはオプションとして示されています。実際には、これはXMLType列でのみ使用され、その場合は必須です。XMLType列以外に使用するとエラーになります。VIRTUALは、XMLType列自体が生成されないことを指定します。つまり、そのデータは、対応するXMLTable表により指定されたリレーショナル列の形式でのみ、索引に格納されます。

6.4 全文問合せ用のXMLデータの索引付け

XMLデータの全文検索を行う必要がある場合は、バイナリXMLとしてXMLTypeデータを格納し、XQuery Full Text (XQFT)を使用することをお薦めします。これには、XML検索索引を使用します。これが、この項の内容です。

移植性やコードの標準化が問題にならない場合や、XMLTypeデータがオブジェクト・リレーショナル形式で格納されている場合は、かわりにOracle固有の全文構造体とOracle Textが提供している構文、具体的にはOracle SQL関数containsまたはOracle XPath関数ora:contains (非推奨)を使用できます。

バイナリXMLとして格納されているXMLTypeデータに対しては、XQuery Full Text (XQFT)問合せを実行できます。SQL WHERE句内のXMLExists式でXQFT全文述語を使用する場合は、XML検索索引を作成する必要があります。この項では、このような索引の作成と使用について説明します。

関連トピック

関連項目:

例6-46

6.4.1 XML検索索引の作成と使用

XQuery Full Text問合せでは、パフォーマンスを高めるためにXML検索索引を使用できます。

XML検索索引を作成するには、データベース・ロールCTXAPPを付与されている必要があります。一般的にこのロールは、Oracle Text索引の作成、Oracle Text索引プリファレンスの設定、またはOracle Text PL/SQLパッケージの使用に必要です。

索引を作成する前に、Oracle Textパス・セクション・グループを作成して、そのXML_ENABLE属性をtに設定する必要があります。これにより、パス・セクション・グループがXML対応になります。

パフォーマンスを向上させるには、Oracle Textデータ・ディクショナリ内にBASIC_STORAGE型の索引プレファレンスを作成して、次の属性を指定します。

  • D_TABLE_CLAUSE: XML文書の構造に関する情報が含まれている索引データ表$Dの列DOCに対して、SECUREFILE記憶域を指定します。キャッシュおよび圧縮レベル(MEDIUM)を指定します。

  • I_TABLE_CLAUSE: 全文トークンと索引付けされた文書でのその出現に関する情報が含まれている索引データ表$Iの列TOKEN_INFOに対して、SECUREFILE記憶域を指定します。キャッシュを指定します(ただし圧縮は不要)。

これについては例6-41で、XML Schemaに基づかないXMLTypepo_binxml (標準のデータベース・スキーマOE内の表purchaseorderと同じデータを持つ)を使用して説明します。

索引プレファレンスBASIC_STORAGEは、Oracle Text索引を構成するデータベース表および索引に対する表領域および作成パラメータを指定します。

関連項目:

例6-42では、データ問合せを実行して、テキストにBigStreetの両方がこの順序で含まれるDescription要素を取得します。

例6-43は、索引po_ctx_idxの取得を指示する、問合せの実行計画を示しています。

例6-41 XML検索索引の作成

BEGIN
  CTX_DDL.create_section_group('mysecgroup', 'PATH_SECTION_GROUP');
  CTX_DDL.set_sec_grp_attr('mysecgroup', 'XML_ENABLE', 'T');

  CTX_DDL.create_preference('mypref', 'BASIC_STORAGE');
  CTX_DDL.set_attribute('mypref',
                        'D_TABLE_CLAUSE',
                        'TABLESPACE my_ts
                         LOB(DOC) STORE AS SECUREFILE 
                         (TABLESPACE my_ts COMPRESS MEDIUM CACHE)');
  CTX_DDL.set_attribute('mypref',
                        'I_TABLE_CLAUSE',
                        'TABLESPACE my_ts
                         LOB(TOKEN_INFO) STORE AS SECUREFILE
                         (TABLESPACE my_ts NOCOMPRESS CACHE)');
END;
/

CREATE INDEX po_ctx_idx ON po_binxml(OBJECT_VALUE)
  INDEXTYPE IS CTXSYS.CONTEXT
  PARAMETERS('storage mypref section group mysecgroup');

例6-42 XQuery Full Text問合せ

SELECT XMLQuery('for $i in /PurchaseOrder/LineItems/LineItem/Description
                   where $i[. contains text "Big" ftand "Street"]
               return <Title>{$i}</Title>'
               PASSING OBJECT_VALUE RETURNING CONTENT)
  FROM po_binxml
  WHERE XMLExists('/PurchaseOrder/LineItems/LineItem/Description
                   [. contains text "Big" ftand "Street"]'
                  PASSING OBJECT_VALUE);

例6-43 XQuery Full Text問合せの実行計画

------------------------------------------------------------------------------------------
| Id  | Operation                   | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |            |     1 |  2014 |     4   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| PO_BINXML  |     1 |  2014 |     4   (0)| 00:00:01 |
|*  2 |   DOMAIN INDEX              | PO_CTX_IDX |       |       |     4   (0)| 00:00:01 |
------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - access("CTXSYS"."CONTAINS"(SYS_MAKEXML(0,"XMLDATA"),'<query><textquery
              grammar="CONTEXT" lang="english"> ( ( {Big} ) and ( {Street} ) )  INPATH
              (/PurchaseOrder/LineItems/LineItem/Description)</textquery></query>')>0)
 
Note
-----
   - dynamic sampling used for this statement (level=2)
   - Unoptimized XML construct detected (enable XMLOptimizationCheck for more information)
 
21 rows selected.

6.4.2 XML検索索引を取得できない場合の対処方法

特定の条件が確実に満たされるように問合せを変更することで、評価によってXML検索索引が取得されるようにできます。

SQL WHERE句内のXMLExists式でXQuery全文述語を使用しながら、XML検索索引を作成しなかったり、なんらかの理由でその索引を使用できない場合には、コンパイル時エラーORA-18177が発生します。

エラーが発生した場合、実行計画では、索引の取得は指示されません。計画には、操作DOMAIN INDEXの後に索引の名前は表示されません。

この場合は、索引を使用できるように問合せを変更してください。取得する索引では、次の条件の両方を満たす必要があります。

  • 検索コンテキストのXMLノードを計算する式は、ステップがforward軸およびdescendent軸のみに沿ったXPath式にする必要があります。

  • SQL/XML関数XMLExistsPASSING句にSQL式として渡すことのできるXMLTypeインスタンスは1つのみで、同じ句内に含まれるその他の非XMLType SQL式はすべて、組込みSQLデータ型のコンパイル時定数、またはこのようなデータ型のインスタンスにバインドされているバインド変数のいずれかである必要があります。

6.4.3 プラグマora:no_schema: XQuery Full TextでのXML Schemaに基づくデータの使用

XQuery Full TextとXML検索索引を使用する場合は、一般に、XML Schemaに基づかないXMLTypeデータの使用をお薦めします。ただし、状況によっては、バイナリXMLとして格納されているXML SchemaベースのXMLTypeデータを使用できます。このコンテキストでは、Oracle XQueryプラグマora:no_schemaが役立つ場合があります。

デフォルトで、XML検索索引を使用してXML Schemaに基づくデータを評価する場合は、コンパイル時エラーORA-18177が発生します。これは、全文索引機能が型を認識しないため、関連付けられたXML Schemaを利用しないことが原因です。適用されるすべてのテキストが型指定なしとして扱われます。このエラーは、データが適切に型キャストされている場合でも発生するため、XML Schemaの暗黙的な型キャストには依存しません。例6-44に、これを示します。

問合せの全文条件が、XML Schema型と型指定された操作に依存することを想定していたユーザーは、発生したエラーによってこれを意識するようになります。

型に依存する条件を使用するためには、関連するXQuery式を明示的に適切な型にキャストする必要があります。Oracle XML DBでは、XML Schemaを使用して暗黙的な型キャストを実行することはありません。型キャストを適切に実行できないと、予期しない結果が生じる可能性があります。

例6-45は、適切な条件が評価されるように型キャストを明示的に指定した、XML Schemaに基づくデータの問合せを示しています。

ただし、XQuery Full Text式を使用する場合は通常、XML Schemaに基づくデータを扱うときでも、型指定されたデータは含めません。型指定されたデータを条件で使用する場合は、適切な型にキャストする必要があるので注意してください。

つまり、型指定されたデータが問合せに含まれていないことがわかっている、または特定の型指定されたデータを型指定されていないデータとして扱っても問題ない、あるいは型指定が必要なデータは明示的に型キャストする場合は、問合せでOracle XQueryプラグマora:no_schemaを使用すれば、エラーの発生を防ぎつつ、XML検索索引を使用して問合せを評価できます。

例6-44 XML Schemaに基づくデータを使用したXQuery Full Text問合せ: エラーORA-18177

SELECT XMLQuery('/PurchaseOrder/LineItems/LineItem'
                PASSING OBJECT_VALUE RETURNING CONTENT)
  FROM oe.purchaseorder
  WHERE XMLExists('/PurchaseOrder
                   [LineItems/LineItem/@ItemNumber > xs:integer("20")
                    and Actions/Action/User contains text "KPARTNER"]'
                  PASSING OBJECT_VALUE);
  FROM oe.purchaseorder
          *
ERROR at line 3:
ORA-18177: XQuery full text expression '/PurchaseOrder
[LineItems/LineItem/@ItemNumber > xs:integer("20")
and Actions/Action/User contains text "KPARTNER"]'
cannot be evaluated using XML text index

例6-45 XML Schemaに基づくデータでのXQueryプラグマora:no_schemaの使用

SELECT XMLQuery('/PurchaseOrder/LineItems/LineItem'
                PASSING OBJECT_VALUE RETURNING CONTENT)
  FROM oe.purchaseorder
  WHERE XMLExists('(# ora:no_schema #)
                   {/PurchaseOrder
                    [LineItems/LineItem/@ItemNumber > xs:integer("20")
                     and Actions/Action/User contains text "KPARTNER"]}'
                  PASSING OBJECT_VALUE);

6.4.4 プラグマora:use_xmltext_idx: XML検索索引の強制的な使用

XQueryプラグマora:use_xmltext_idxを使用して、XML検索索引の使用を強制できます。

XMLデータを使用する問合せは、存在する索引の種類や数などによって、様々な方法で評価できます。デフォルトの評価方法が最もパフォーマンスに優れているとはかぎらず、既存のXML検索索引を強制的に使用した方がより効率的な場合があります。XQueryプラグマora:use_xmltext_idxを使用すれば、これを行うことができます。(XML検索索引は、バイナリXMLとして格納されているXMLTypeデータにのみ適用されます。)

たとえば、WHERE句に2つのXMLExists式があり、いずれか一方にのみXQuery Full Textの条件が含まれ、全文条件がない方のXMLExists式にはXMLIndex索引を適用するとします。このような問合せでは、通常、XML検索索引を使用してWHERE句全体を評価した方がより効率的です。

問合せに全文条件がない場合でも、XML検索索引を使用することによって、問合せの評価の効率性が向上する可能性があります。

例6-46の問合せでは、プラグマora:use_xmltext_idxの使用方法を示しています。XMLExistsの最初の句にのみ全文条件が使用されています。プラグマが指定されているので、全文索引(po_ctx_idx例6-41で作成)は、両方のXMLExists句で使用されます。

例6-46 XQueryプラグマora:use_xmltext_idxを使用した全文問合せ

SELECT XMLQuery('/PurchaseOrder/LineItems/LineItem'
                PASSING OBJECT_VALUE RETURNING CONTENT)
  FROM po_binxml
  WHERE XMLExists('/PurchaseOrder/LineItems/LineItem
                   [Description contains text "Picnic"]' PASSING OBJECT_VALUE)
    AND XMLExists('(# ora:use_xmltext_idx #) {/PurchaseOrder[User="SBELL"]}'
                  PASSING OBJECT_VALUE);

6.4.5 Oracle Text索引の使用からXML検索索引への移行

バイナリXMLとして格納されているXMLTypeデータに対するレガシー問合せで、SQL関数CONTAINSまたは非推奨のXPath関数ora:containsと、XML非対応のOracle Text索引が使用されている場合は、かわりにXQuery Full Text構造体を使用することを検討してください。

XQuery and XPath Full Text (XQFT)標準は、Oracle Database 12cリリース1 (12.1)からOracle XML DBでサポートされるようになりました。このサポートは、バイナリXMLとして格納されているXMLTypeデータにのみ適用されます。そのリリースより前は、XMLデータの全文問合せに使用できたのはXML非対応のOracle Text索引のみ(XML検索索引ではなく)だったので、全文問合せでは必ずOracle固有の構造体(SQL関数CONTAINSまたはXPath関数ora:contains (非推奨))が使用されていました。

これを使用しているレガシー・コードがある場合は、そのコードを移行してXQFTを使用することをお薦めします。この項では、問合せで使用されているCONTAINSおよびora:containsを置き換える場合に使用できるXQFTの構造体について説明します。

Oracle Text索引のこのような使用方法は、XML検索索引を使用することで代替できます。HASPATHを使用する問合せを簡単なXQuery式を使用する問合せで置き換えるには、Oracle XQueryプラグマora:use_xmltext_idxを使用して、XML検索索引を取得するように指定します。この項では、これについても説明します。

表6-9に、Oracle固有の構造体を使用する一般的な問合せからXQuery Full Textを使用する問合せへのマッピングを示します。

表6-9 Oracle固有のXML問合せのXQuery Full Textへの移行

元の例 置換後の例
CONTAINS(t.x, 'HASPATH (/P/LIs/LI/DescriptionFoot 3)') > 0
XMLExists('(# ora:use_xmltext_idx #) 
           {$d/P/LIs/LI/DescriptionFootref 3}'
          PASSING t.x AS "d")

または、データがXML Schemaに基づく場合:

XMLExists('(# ora:use_xmltext_idx #)
           {(# ora:no_schema #) 
            {$d/P/LIs/LI/DescriptionFootref 3}}'
          PASSING t.x AS "d")
CONTAINS(t.x, 'Big INPATH
               (/P/LIs/LI/Description)') > 0
XMLExists('$d/P/LIs/LI/Description
           [. contains text "Big"]'
          PASSING t.x AS "d")

または、データがXML Schemaに基づく場合:

XMLExists('(# ora:no_schema #)
           {$d/P/LIs/LI/Description
           [. contains text "Big"]}'
          PASSING t.x AS "d")
XMLExists('$d/P/LIs/LI/Description
           [ora:contains(., "Big AND Street") > 0]'
          PASSING t.x AS "d")
XMLExists('$d/P/LIs/LI/Description
           [. contains text "Big" ftand "Street"]'
          PASSING t.x AS "d")
CONTAINS(t.x, '(Big) AND (Street) INPATH
               (/P/LIs/LI/Description)') > 0
XMLExists('$d/P/LIs/LI/Description
           [. contains text "Big" ftand "Street"]'
          PASSING t.x AS "d")
CONTAINS(t.x, '(Big) OR (Street) INPATH
               (/P/LIs/LI/Description)') > 0
XMLExists('$d/P/LIs/LI/Description
           [. contains text "Big" ftor "Street"]'
          PASSING t.x AS "d")
CONTAINS(t.x, '({Big}) NOT ({Street}) INPATH
               (/P/LIs/LI/Description)') > 0
XMLExists('$d/P/LIs/LI/Description
           [. contains text
            "Big" ftand ftnot "Street"]'
          PASSING t.x AS "d")
CONTAINS(t.x, '({Street}) MNOT ({Big Street}) INPATH
               (/P/LIs/LI/Description)') > 0
XMLExists('$d/P/LIs/LI/Description
           [. contains text
            "Street" not in "Big Street"]'
          PASSING t.x AS "d")
CONTAINS(t.x, '(NEAR (({Big}, {Street}), 3) INPATH
               (/P/LIs/LI/Description)') > 0
XMLExists('$d/P/LIs/LI/Description
           [. contains text
            "Big" ftand "Street" window 3 words]'
          PASSING t.x AS "d")

(適用なし: Oracle Text問合せはXML名前空間に非対応)

XMLExists('declare namespace
           ipo="http://www.example.com/IPO";
           /ipo:P/ipo:LIs/ipo:LI/ipo:Description
           [. contains text "Big"]'
          PASSING t.x AS "d")

脚注3

パスのテストには述語式を含めることができ、それは元の問合せ(HASPATHを使用)でも置換後の問合せでも同じです。例: /PurchaseOrder/LineItems/LineItem/Part[@Id < "31415927"]

6.5 オブジェクト・リレーショナル形式で格納されたXMLTypeデータの索引付け

XMLノードに対応する基礎となるデータベース列に対してBツリー索引を作成することで、オブジェクト・リレーショナル形式で格納されたXMLTypeデータを効果的に索引付けできます。

索引付けされるデータが単一の場合、つまりXMLインスタンス文書で一度のみ発生する可能性がある場合、表面的上ファンクション索引を作成するショートカットを使用できます。この場合、索引を定義する式はファンクション・アプリケーションで、単一データをターゲットとするXPath式の引数を使用します。ショートカットはXMLQueryに適用されるXMLCastに対して定義され、もう1つのショートカットはOracle SQL関数extractValueに対して定義されます(非推奨)。

多くの場合、Oracle XML DBでは、基礎となるオブジェクト・リレーショナル表または列に対して適切な索引が自動的に作成されますが、CREATE INDEX文が示すように、ターゲットとなるXMLTypeデータに対して、ファンクション索引は作成されません

extractValueショートカットの場合、作成される索引はBツリー索引です。XMLQueryに適用されるXMLCastの場合、作成される索引は、ファンクション式から得られるスカラー値に対するファンクション索引です。

索引付けされるデータがコレクションの場合、このようなショートカットを使用できません。手動でBツリー索引を作成する必要があります。

6.5.1 繰り返し使用しないテキスト・ノードまたは属性値の索引付け

サンプル・データベース・スキーマOEの表purchaseorderはオブジェクト・リレーショナルに格納されます。各発注書には単一のReference要素が含まれます。つまりこの要素は単一です。したがって、ショートカットを使用して、基礎となるオブジェクト・リレーショナル・データに索引を作成できます。

例6-47に、Reference要素のテキスト・コンテンツをターゲットとし、XMLQueryに適用されるXMLCastを使用して、表面上ファンクション索引を作成しようとするCREATE INDEX文を示します。(この要素のコンテンツはテキストのみのため、要素をターゲットにすることは、XPathノード・テストtext()を使用してテキスト・ノードをターゲットにすることと同じです。)

例6-48は、同じデータをターゲットにし、Oracle SQL関数extractValue(非推奨)を使用して表面上ファンクション索引を作成します。

実際、例6-47例6-48では、ターゲットとなるXMLTypeデータに対してファンクション索引は作成されません。かわりに、Oracle XML DBによってCREATE INDEX文がリライトされ、基礎となるスカラー・データに対して索引が作成されます。

関連項目:

このようなCREATE INDEX文に適用されるXPathリライトの詳細は、例19-7および例19-8を参照してください。

これらのショートカットのいずれかを使用するとき、CREATE INDEX文は前述のように基礎となるスカラー・データ上に索引を作成できない場合があります。そのかわり、実際には参照されるXMLTypeデータにファンクション索引を作成します。(これは索引のがスカラーである場合でも当てはまります)。

このような場合は、索引を削除し、同じXPathをターゲットとする構造化コンポーネントを含むXMLIndex索引をかわりに作成します。一般的に、XMLTypeデータに対してはファンクション索引を使用しないことをお薦めします。

これは使用される格納方法にかかわらず、XMLTypeデータの一般的なルールです。ファンクション索引のかわりに構造化コンポーネントでXMLIndexを使用します。このルールはOracle Database 11gリリース 2 (11.2)から適用されます。このルールを守ることにより、ファンクション索引のメンテナンス操作に関連するオーバーヘッドを軽減し、オプティマイザで索引を適切に選択できる状況が増えます。

例6-47 単一の要素でXMLCASTおよびXMLQUERYを使用したCREATE INDEX

CREATE INDEX po_reference_ix ON purchaseorder
  (XMLCast(XMLQuery ('$p/PurchaseOrder/Reference' PASSING po.OBJECT_VALUE AS "p"
                                                  RETURNING CONTENT)
              AS VARCHAR2(128)));

例6-48 単一の要素でEXTRACTVALUEを使用したCREATE INDEX

CREATE INDEX po_reference_ix ON purchaseorder
  (extractValue(OBJECT_VALUE, '/PurchaseOrder/Reference'));

6.5.2 繰り返し使用する(コレクション)要素の索引付け

オブジェクト・リレーショナル形式で格納されたXMLTypeデータでは、コレクションはXMLTypeインスタンスのOrdered Collection Table (OCT)として格納されるため、メンバーに直接アクセスできます。オブジェクト・リレーショナル記憶域は、XMLデータのファイングレイン構造を直接反映するため、各コレクション・メンバーをターゲットとする索引を作成できます。

このような索引は、手動で作成する必要があります。Oracle SQL関数extractValue(非推奨)に対して表面上ファンクション索引を作成する場合に、Bツリー索引を自動的に作成する専用の機能は、コレクションに適用されません(extractValueに渡されるXPath式は、単一要素をターゲットにする必要があります)。

コレクションに対してBツリー索引を作成するには、コレクションの管理に使用するSQLオブジェクトの構造を理解する必要があります。その情報に基づき、従来のオブジェクト・リレーショナルSQLコードを使用して、適切なSQLオブジェクト属性に対して索引を直接作成できます。この方法の例は、ガイドライン: Ordered Collection Tableに対する索引の作成を参照してください。



脚注の説明

脚注1:

オブジェクト・リレーショナル形式で格納されているXMLTypeデータについては、オブジェクト・リレーショナル形式で格納されたXMLTypeデータの索引付けを参照してください。データの構造化が高度に進んでいる場合、または索引の作成時点で問合せが既知でない場合には、この方法が適している可能性があります。


脚注2:

実際のパス表の実装は多少異なることがあります。