6 XMLTypeデータの索引
頻繁に問い合せるXMLデータの特定部分に着目できるよう当該XMLデータに対して索引を作成し、パフォーマンスを向上できます。XML Schemaに基づくかどうか、および使用されるXMLType
記憶域モデルに関係なく、XMLType
データに索引付けできる様々な方法があります。
ノート:
ここで示す実行計画は、説明のためのみに使用しています。ここで示す例を実際の環境で実行しても、実行計画が同一になるわけではありません。
関連項目:
-
索引付けの概要は、Oracle Database概要を参照してください。
-
アプリケーション開発における索引付けの使用方法の詳細は、Oracle Database開発ガイドを参照してください。
索引に関連するOracle XML DBのタスク
XMLデータの索引に関連する一般的なタスクについて説明します。
表6-1は、XMLデータの索引付けに関連するいくつかの基本的なユーザー・タスクの参照先を示します。
表6-1 基本的なXML索引付けタスク
操作の詳細 | 参照先 |
---|---|
索引付けの方法の選択 |
|
オブジェクト・リレーショナル形式で格納された |
オブジェクト・リレーショナル形式で格納されたXMLTypeデータの索引付け、ガイドライン: Ordered Collection Tableに対する索引の作成 |
|
|
特定の表または列に対する |
|
指定された |
|
|
表6-2は、構造化
コンポーネントを含むXMLIndex索引付けに関連するいくつかのユーザー・タスクの参照先を示します。
表6-2 構造化コンポーネントを含むXMLIndex索引に関連するタスク
操作の詳細 | 参照先 |
---|---|
構造化コンポーネントが含まれる |
|
|
|
構造化コンポーネントが含まれる |
|
|
|
|
表6-3は、非構造化
コンポーネントを含むXMLIndex索引付けに関連するいくつかのユーザー・タスクの参照先を示します。
表6-3 非構造化コンポーネントを含むXMLIndex索引に関連するタスク
操作の詳細 | 参照先 |
---|---|
非構造化コンポーネントが含まれる |
|
|
|
|
|
|
|
|
|
|
|
パス表の指定による、非構造化コンポーネントが含まれる |
|
|
|
|
|
パス表の |
|
パス表の |
|
パス表の |
|
パス表の |
|
|
|
|
|
|
|
|
表6-4は、XMLIndex
索引付けに関連するその他のユーザー・タスクの参照先を示します。
表6-4 XMLIndex索引に関連するその他のタスク
操作の詳細 | 参照先 |
---|---|
|
|
|
|
|
|
|
|
コストベース・オプティマイザに対する表または索引に関する統計の収集 |
|
XML検索索引の作成 |
|
バイナリXMLとして格納されているXMLデータの全文検索におけるXML検索索引の使用 |
|
XML検索索引が問合せで使用されているかどうかの表示 |
|
|
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データを索引付けする必要はありません。
-
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データでも、高度に構造化された予測可能な部分に索引付けします。この索引コンポーネントは、構造化コンテンツのアイランドを投影および使用する問合せで特に便利です。
関連トピック
XMLデータのためのOracle Text索引
要素や属性などのXMLノードにアクセスする以外にも、XMLテキスト・ノード内の特定の節に対して高速アクセスを提供する必要があることがあります。XMLデータ内でこのようなコンテンツの問合せを行うには、XQuery Full Text (XQFT)またはOracle固有の全文構造体を使用できます。
いずれの場合も、適切なOracle Text (全文)索引が作成されます。XQFTの場合、索引はXML検索索引であり、バイナリXMLとして格納されたXMLType
データでの使用に特化した設計になっています。
全文索引は、特に、XML要素とテキストノード・コンテンツが混在する、文書中心のアプリケーションにおいて有用です。全文検索は、構造化XML検索と組み合せる(XPath式によって識別されるXML文書の一定部分に対して検索を限定する)ことによってさらに強力に、焦点を絞って行えるようになります。
関連トピック
最適化による、使用する適切な索引の選択
1つのケースで複数の索引が該当する場合は、どの索引が使用されるでしょうか。パフォーマンスを最大化する索引(複数可)は、コストベースの最適化によって決定されます。
Oracle Text索引はテキストにのみ適用されるため、XMLデータではテキスト・ノードを意味します。テキスト・ノードがターゲットとされ、対応するOracle Text索引が定義されている場合は、Oracle Text索引が使用されます。特定のコンテキストにおいて他の索引も適している場合は、これらも使用されます。ただし、単に索引が定義され、特定の状況に適用可能に見えることは、必ずしもその索引が使用されことを意味しません。コストベース・オプティマイザによって費用効率が低いと判断されたものは、使用されません。
XMLTypeに対するファンクション索引の非推奨化
Oracle Database 11gリリース2(11.2)以前のリリースでは、XPath式が単一ノードをターゲットにしている場合、XMLType
データにおいてファンクション索引の使用が適していることもありました。かわりに、XMLIndex
の構造化コンポーネントを使用することをお薦めします。
これにより、ファンクション索引のメンテナンス操作に関連するオーバーヘッドを軽減し、オプティマイザで索引を適切に選択できる状況が増えます。その結果、既存のDML文の変更が不要になります。
さらに、XMLType
のオブジェクト・リレーショナル記憶域では、Oracle SQL関数extractValue
(非推奨)で索引を定義すると、XPathリライトにより、(extractValue
に対してファンクション索引ではなく)基礎のオブジェクトに対してBツリー索引が自動的に作成されることがあります。XPathのターゲットは単一の要素または属性である必要があります。XMLQuery
に適用されるXMLCast
に対しても、同様のショートカットが存在します。
XMLIndex
ノート:
非構造化XML索引は23cでは非推奨であり、XML検索索引に置き換えられています。かわりに構造化XML索引およびXML検索索引を使用することをお薦めします。
XMLIndexの利点
オブジェクト・リレーショナル形式のXMLType
記憶域では、Bツリー索引を効果的に使用できます。基礎となるオブジェクトを直接ターゲット化することで、焦点がより明確に絞られます。ただし、バイナリXMLを使用して格納されているXML文書の詳細な構造(要素および属性)を指定する場合、通常は効果を発揮しません。これはXMLIndex
の特殊ドメインです。
XMLIndex
はドメイン索引で、XMLデータのドメイン用に特化して設計されています。これは論理的索引です。XMLIndex
索引は、SQL/XML関数XMLQuery
、XMLTable
、XMLExists
およびXMLCast
に対して使用できます。
XMLIndexには、他の索引付け方式に比べ、次のような利点があります。
-
XMLIndex
索引は、問合せのどの部分においても効果があります。つまり、WHERE
句での使用に限定されません。これは、XMLデータで使用される他の種類の索引では考えられません。 -
非構造化コンポーネントを含む
XMLIndex
索引では、SELECT
リスト・データとFROM
リスト・データの両方に対するアクセスを高速化でき、特にXMLフラグメント抽出において有用です。ファンクション索引は非推奨になったため、文書のフラグメントの抽出には使用できません。 -
XMLIndex
索引は、XML Schemaに基づく/基づかないにかかわらず、バイナリXMLとして格納されているXMLTypeデータに対して使用できます。Bツリー索引は、オブジェクト・リレーショナル形式で格納されるXML Schemaに基づくデータにのみ適しています。 -
XMLIndex
索引は、コレクション(文書内に複数回出現するノード)をターゲットとするXPath式による検索において使用できます。ファンクション索引の場合とは異なります。 -
問合せに使用されるXPath式に関する事前の知識は不要です。
XMLIndex
索引の非構造化コンポーネントは、汎用性に富んでいます。ファンクション索引の場合とは異なります。 -
問合せに使用されるXPath式が事前にわかっている場合は、頻繁に問合せされる構造化された固定のデータ・アイランドをターゲットとする構造化
XMLIndex
コンポーネントを使用することで、パフォーマンスを向上できます。 -
XMLIndex
索引(索引の作成とメンテナンス)は、複数のデータベース処理により、並列的に実行できます。非推奨になったファンクション索引の場合とは異なります。
構造化XMLIndexコンポーネントと非構造化XMLIndexコンポーネント
XMLIndex
を使用して非構造化または半構造化のXMLデータ(一般的にほとんどまたはまったく固定構造を持たないデータ)を索引付けします。それは、バイナリXMLとして格納されるXMLType
データに適用されます。
ノート:
非構造化XML索引は23cでは非推奨であり、XML検索索引に置き換えられています。Oracleでは、非構造化XML索引をXML検索用索引として再作成することをお奨めします。
それでも、半構造化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列目)。
関連項目:
各XMLIndex
コンポーネント・タイプで提供される利点の概要は、XMLIndexの利点参照してください。
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 BY
、GROUP 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言語リファレンスを参照してください。
透過的な索引コンテンツ表の無視
XMLIndex
構造化コンポーネントの索引コンテンツ表は通常のリレーショナル表ですが、読取り専用の表でもあるため、表の列を追加または削除したり、表の行を変更(挿入、更新または削除)したりすることはできません。
したがって、通常はリレーショナル索引コンテンツ表は無視してかまいません。DESCRIBE
したり、(2次)索引を作成する以外、それらにアクセスできません。それらに関する統計を明示的に収集する必要はありません。XMLIndex
索引自体、またはXMLIndex
索引が定義されている実表に関する統計のみ収集する必要があります。索引コンテンツ表に関する統計は透過的に収集され保持されます。
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データ型 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ノート:
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");
パーティション交換とXMLIndex
パーティション交換では、1つの表と、別の表のパーティションを変更します。最初の表には、交換対象となる2番目の表のパーティションと同じ構造が含まれている必要があります。2つの表はXMLIndex
索引による索引付けという点でも類似している必要があります。
次の条件の1つに該当している必要があります。
-
どちらの表にも
XMLIndex
索引がないこと。 -
どちらにも
XMLIndex
索引があり、次のいずれかが当てはまること。-
どちらの索引にも構造化コンポーネントがない。
-
どちらの索引にも構造化コンポーネントがある。
-
これらの条件のいずれも当てはまらない場合、パーティション交換は実行できません。
どちらの表でも構造化コンポーネントにXMLIndex
索引がある場合は、通常、ALTER TABLE EXCHANGE PARTITION
を呼び出す前に一定の前処理を実行する必要があり、呼出し後にも一定の後処理を実行する必要があります。そうしないと、exchange-partition操作でエラーが発生します。
この前処理と後処理を実行するには、例6-3のようにパッケージDBMS_XMLSTORAGE_MANAGE
のPL/SQLプロシージャexchangePreProc
とexchangePostProc
を使用します。XMLType
の各表、table
とexchange_table
には、構造化コンポーネントを持つXMLIndex
索引があります。
参照パーティション表の特殊なケースでは、外部キー制約が関連するため、状況は少し複雑になります。この場合、PL/SQLプロシージャrefPartitionExchangeIn
またはrefPartitionExchangeOut
をそれぞれ使用して、データをパーティション表にロード(exchange-in)またはパーティション表からロード(exchange-out)します。
例6-4では、交換対象の表parent_ex
およびchild_ex
から実表parent
およびchild
にデータをロードし、これを示します。例6-5に、表と索引の定義を示します。
関連項目:
-
ドメイン索引(
XMLIndex
はドメイン索引)を持つ表でのALTER TABLE EXCHANGE PARTITION
の使用方法の詳細は、Oracle Databaseデータ・カートリッジ開発者ガイドを参照してください。 -
パッケージ
DBMS_XMLSTORAGE_MANAGE
のプロシージャexchangePreProc
、exchangePostProc
、refPartitionExchangeIn
およびrefPartitionExchangeIOut
の詳細は、Oracle Database PL/SQLパッケージおよびタイプ・リファレンスを参照してください。
例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
は、XMLType
列xcol
を含む子の参照パーティション表です。 -
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''');
XMLIndex非構造化コンポーネント
Bツリー索引は、個々のXML要素または属性を表す特定のデータベース列や、構造化ドキュメントの特定部分に適用されるXMLIndex
構造化コンポーネントに対して定義します。これに対し、XMLIndex
索引の非構造化コンポーネントは、デフォルトで非常に汎用性に富んでいます。
非構造化XML索引は23cでは非推奨であり、XML検索索引に置き換えられています。Oracleでは、非構造化XML索引をXML検索用索引として再作成することをお奨めします。
索引付けに使用する特定の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 XMLIndexのパス表
列 | データ型 | 説明 |
---|---|---|
|
|
ノードのXPathパスに対する一意の識別子です。 |
|
|
XMLデータを格納するために使用される表のROWIDです。 |
|
|
ノードの階層的な位置を識別するための、10進数の順序キーです。(ドキュメントの順序は保持されます。) |
|
|
フラグメント位置情報です。フラグメント抽出に使用されます。XML Schemaに基づくデータのバイナリXML記憶域では、データ型情報もここに格納されます。 |
|
|
ノードの有効テキスト値。 |
pikey索引では、パス表の列PATHID
、RID
および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 |
---|---|
|
|
|
|
|
|
|
|
|
|
結果として作成されるパス表は、次のようになります(LOCATOR
列は示されません)。
PATHID | RID | ORDER_KEY | VALUE |
---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
表パスは透過的であり、無視
パス表の列に2次索引を作成した場合でも、パス表そのものは通常は無視できます。
パス表には、それをDESCRIBEしたり、(2次)索引を作成したりする以外はアクセスできません
。パス表に関する統計を明示的に収集する必要はありません。統計は、XMLIndex
索引、またはXMLIndex
索引が定義されている実表についてのみ収集する必要があります。統計は収集され、パス表と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
列で使用されます。
VALUE列に対する2次索引
XMLIndex
索引を作成する際、VALUE
列に対して2次索引を指定しない場合でも、VALUE
列に対してデフォルトの2次索引が作成されます。このデフォルト索引には、デフォルトのプロパティがあります。具体的には、これはtext(文字列値)データでのみ使用される索引です。
ただし、異なる種類のVALUE
索引を作成できます。たとえば、数値の索引が問合せの大半に適している場合は、数値の索引を作成できます。VALUE
列に対し、複数の2次索引を作成できます。特定の種類の索引は、それが適切な場合にのみ使用されます。たとえば、数値の索引は、VALUE
列が数値である場合にのみ使用されます。その他の値の場合は無視されます。パス表の列の2次索引は、その他の2次索引と同様に扱われます。つまり、これらの索引は変更、削除、不使用としてマーキングするなどが可能です。
関連項目:
-
VALUE
列に2次索引を作成する例は、非構造化コンポーネントを含むXMLIndexの使用を参照してください。 -
PARAMETERS
句の構文は、CREATE INDEXおよびALTER INDEXのPARAMETERS句を参照してください。
XMLIndex索引の作成、削除、変更、および検証
XMLIndex
索引に対する基本操作には、XMLIndex索引の作成、削除、変更および検証が含まれます。例を示します。
例6-7に示すように、索引タイプをXDB.XMLIndex
と宣言して、XMLIndex
索引を作成します。
これにより、XMLType
のpo_binxml
表に、po_xmlindex_ix
という名前のXMLIndex
索引が作成されます。索引に含まれるのは非構造化コンポーネントのみで、構造化コンポーネントは含まれません。
XMLIndex
索引に構造化コンポーネントを含めるように指定するには、PARAMETERS
句にstructured_clause
を含めます。非構造化コンポーネントを含めるように指定するには、PARAMETERS
句にpath_table_clause
を含めます。
この操作は、XMLIndex
索引を作成または変更する場合に可能です。例6-7に示すように、structured_clause
とpath_table_clause
のいずれも指定しない場合は、非構造化コンポーネントのみが含まれます。
XMLIndex
索引に非構造化コンポーネントと構造化コンポーネントの両方が含まれる場合は、ALTER INDEX
を使用していずれかのコンポーネントを削除できます。
例6-8に示すように、特定のXMLType
表(または列)のXMLIndex
索引の名前を取得できます。また、適宜DBA_INDEXES
またはALL_INDEXES
からINDEX_NAME
を選択することも可能です。
例6-9に示すように、XMLIndex
索引は、他の索引と同様に名前変更または削除できます。この名前変更では、XMLIndex
索引の名前のみが変更されます。この処理ではパス表の名前は変更されません。パス表は、個別に名前を変更できます。
同様に、REBUILD
などのALTER INDEX
オプションを使用し、他の索引プロパティも変更できます。この点においては、XMLIndex
も他の索引タイプと同じです。
XMLIndex
のALTER 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;
非構造化コンポーネントを含む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.
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要素のテキスト値に対する全文問合せにおいて便利です。CONTEXT
索引がVALUE
列に対して定義されている場合、述語の評価時に使用されます。Oracle Text索引は、他のすべてのVALUE
列の索引に依存しません。
例6-20の問合せは、XMLIndex
索引のパス表に対して作成されたすべての2次索引を示します。作成された索引は、明確に太字で示されます。特に注意する必要があるのは、VALUE
列に作成されたファンクション索引などは、この例のように表示されない点です。これらの索引の列名は、SYS_NC00007$
などのシステム生成名になります。そのため、WHERE句でCOLUMN_NAME = 'VALUE'
を使用して問合せを実行しても、これらの列を見ることはできません
。
関連項目:
-
VALUE
列に対して作成されたOracle TextCONTEXT
索引が間違った結果を戻すことがあります。この詳細は、「XMLIndexパス表のVALUE列」を参照してください。 -
CREATE INDEX
パラメータTRANSACTIONAL
の詳細は、Oracle Textリファレンスを参照してください。 -
DBMS_XMLINDEX
パッケージのPL/SQLプロシージャcreateNumberIndex
およびcreateDateIndex
の詳細は、Oracle Database PL/SQLパッケージおよびタイプ・リファレンスを参照してください。
例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.
関連トピック
構造化コンポーネントを含む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
式を正確に記述できます。
関連項目:
-
DBMS_XMLSTORAGE_MANAGE.getSIDXDefFromView
の使用方法の詳細は、リレーショナル・ビューを使用して公開されたバイナリXMLデータの索引付けを参照してください。 -
XMLTable
句のXMLType
列の詳細は、XMLIndex_xmltable_clauseの使用を参照してください。 -
キーワード
COLUMNS
およびVIRTUAL
の詳細は、column_clauseの使用を参照してください。
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)');
XMLIndex索引への構造化コンポーネントの追加
ALTER INDEX
を使用して、既存のXMLIndex
索引に構造化コンポーネントを追加できます。
例6-23に、非構造化コンポーネントのみを含むXMLIndex
索引を作成する方法を示します。PARAMETERS
句でパス・ノードに明示的に名前付けしているため、非構造化コンポーネントが作成されます。
例6-23では、ALTER INDEX
を使用して、po_item
という名前の構造化コンポーネント(グループ)を追加します。この構造グループには、キーワードXMLTable
で指定された2つのリレーショナル表が含まれます。
最上位の表po_idx_tab
には、reference
、requestor
、username
およびlineitem
の列があります。lineitem
列の型はXMLType
です。この列はコレクションを表しているため、2番目のXMLTable
構造体に渡されて、2番目のレベルのリレーショナル表po_index_lineitem
を構成します。この表には、列itemno
、description
、partno
、quantity
および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');
XMLIndex構造化コンポーネントでの非ブロック・モードによるALTER INDEXの使用
XMLIndex
索引の構造化コンポーネントにグループまたは列を追加する際に、ALTER INDEX
によるブロックを回避できるため、この索引を使用する問合せでは、待機する必要はありません。
ALTER INDEX
を使用して、XMLIndex
索引の構造化コンポーネントにグループまたは列を追加する場合、この索引メンテナンス操作では、実表および索引に対して排他DDLロックを取得します。
ALTER INDEX
操作が終了するまで、実表はDML操作に対してロックされ、索引を問合せで使用することはできません。つまり、この索引メンテナンス中は、実表に対して問合せやDML操作を実行する別のセッションから索引を使用することはできません。ALTER INDEX
操作とそれに附随するロックの期間は、XMLType
の実列に含まれているデータ量によって異なります。
この問題を回避するには、次の手順を実行します。
-
構造化コンポーネントのグループまたは列を作成する
ALTER INDEX
文のPARAMETERS
句で、ADD_GROUP
またはADD_COLUMN
の前にキーワードNONBLOCKING
を指定します。これにより、必要に応じて索引は更新されますが、実表のデータは索引付けされません。実表のデータに依存しないため、実表のサイズに関係なく高速です。
-
PL/SQLプロシージャ
DBMS_XMLINDEX.
process_pending
を呼び出します。このプロシージャでは、キーワード
NONBLOCKING
が指定されていないかのように、実表の行に索引付けして索引の表にデータを移入します。ただし、この場合、処理および変更のコミットが行われている間にロックされる行はわずか数行です。他の目的ですでにロックされていた行はスキップされます。これにより、ロック競合が大幅に減少し、一部の行への索引付けを可能にしつつ、同時に、その他の行に対して問合せやDML操作を実行できます。プロシージャ
process_pending
が終了すると、次のOUT
パラメータを戻します。-
索引付けできなかった行の数。この原因は、それらが他の目的でロックされていたか、エラーが発生したためかのいずれかです(この数には、もう1つの
OUT
パラメータとして戻された数も含みます)。これらのロックが解除されたことを確認した後で、プロシージャ
process_pending
をもう一度呼び出して、保留中の行の処理を試みます。 -
エラーが発生したために索引付けできなかった行の数(これはまれなケースです)。
表
SYS_AIXSXI_
index_number
_ERRORTAB
でエラーの詳細を確認し、問題の原因を解決するための処置を取ります。index_number
とは、索引オブジェクト番号のことです。
-
-
すべての行が正常に索引付けされたことをプロシージャprocess_pendingが示すか、解決できない問題が発生して索引付けの操作を完全にキャンセルする判断をユーザーが下すまで、ステップ
2
を必要な回数繰り返します。同じ
XMLIndex
索引に対し、別のALTER INDEX
文のPARAMETERS
句で、キーワードNONBLOCKING ABORT
を指定することにより、索引付けは(ステップ2の前に)いつでもキャンセルできます。 -
すべての行が正常に索引付けされた場合は、同じ
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');
構造化XMLIndexコンポーネントのデータ型の変更
データの一部が構造化XMLIndex
コンポーネントの対応する列で使用されているデータ型と一致しないためにエラーが発生する場合は、キーワードMODIFY_COLUMN_TYPE
をALTER INDEX
に渡すことによって、索引を簡単に変更できることがあります。
たとえば、VARCHAR2(30)
列にデータを40文字まで収容する必要がある場合は、それをVARCHAR2(40)
などに拡張できます。列を削除してから新しい列を追加するよりも、この方が簡単でより効率的です。ただし、ALTER TABLE MODIFY COLUMN
と同じ制約が適用されるので、新旧のデータ型が一致している必要があります。
関連項目:
-
ALTER TABLE MODIFY COLUMN
の詳細は、Oracle Database SQL言語リファレンスを参照してください。
構造化XMLIndexコンポーネントのリレーショナル表への索引付け
XMLIndex
索引の構造化コンポーネントに使用する表は通常のリレーショナル表であるため、標準的な任意のリレーショナル索引を使用して、これらの表に索引付けできます。
詳細は、XMLIndex構造化コンポーネントの項を参照してください。例6-26に、これを示します。この例では、例6-23のXMLIndex
索引に対して、索引コンテンツ表(構造化フラグメント)のreference
列にBツリー索引を作成します。
例6-26 XMLIndex索引コンテンツ表に対するBツリー索引の作成
CREATE INDEX idx_tab_ref_ix ON po_idx_tab (reference);
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で作成)が問合せで使用されることを示します。同様に、LOCATOR
、ORDER_KEY
、およびPATHID
の各列への参照も、同じことを示します。
例6-28に示すように、このような実行計画からパス表の名前から、XMLIndex
索引の名前を取得できます。(これは例6-11の問合せとほぼ反対のケースです。)
XMLIndex
は、SELECT
リスト、FROM
リスト、および問合せのWHERE句
のXPath式で使用でき、SQL/XML関数XMLQuery
、XMLTable
、XMLExists
およびXMLCast
において有用です。ファンクション索引(XMLType
では非推奨)とは異なり、XMLIndex
索引は、文書内のXMLフラグメントからデータを抽出する際に使用できます。
例6-29に、これを示します。
例6-29の問合せの実行計画は、パス表を参照することにより、XMLIndex
が使用されることを示します。Oracle内部SQL関数sys_orderkey_depth
が使用されることも示します。非構造化コンポーネントを含むXMLIndexを使用するためのガイドラインを参照してください。
例6-30に、例6-23で作成したXMLIndex
索引が2つのWHERE
句述語を使用する問合せに対して選択されることを示す実行計画を示します。それは例6-51と同じ問合せで、実行計画にも示されているように、同じ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.
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");
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
の索引付けを適用しないようにするには、パスのサブセット化を明示的に使用してそれらを除外する必要があります。
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"))');
XMLIndexパスのサブセット化のルール
XMLIndex
パスのサブセット化に適用されるルールについて説明します。
-
パスはchild軸およびdescendant軸のみを参照し、さらに、要素ノードおよび属性ノード、またはその名前(ワイルドカードを使用可能)のみをテストする必要があります。特に、パスには述語を含めないでください。
-
パス除外とパス包含を一度に指定できません。いずれかの方法を指定する必要があります。
-
パス除外(包含)によって索引が作成された場合は、パス除外(包含)によってのみ修正が可能です。索引の修正は、パスのサブセット化をさらに制限するか、さらに拡張するかのいずれかです。たとえば、特定のパスを含める索引を作成した後に、特定のパスを除外するよう修正することはできません。
非構造化コンポーネントを含むXMLIndexを使用するためのガイドライン
非構造化コンポーネントを含むXMLIndex
を使用する際に役立つ複数のガイドラインがあります。
これらのガイドラインは、ここで説明する2つの方法によって同じ結果セットが戻される場合にのみ該当します。
-
祖先要素の接頭辞として
//
を付加しないでください。たとえば、同じ結果セットを戻す場合、/a/b
//c
ではなく、//c
を使用します。 -
祖先要素の接頭辞として
/*
を付加しないでください。たとえば、同じ結果セットを返す場合、/a
/*/*
ではなく、/*/*/*
を使用します。 -
WHERE
句では、XMLQuery
のXMLCast
ではなく、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を参照してください。
構造化コンポーネントを含む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
索引を使用する場合は、特に使用を避けてください。
XMLIndexのパーティション化および並列度
レンジ・パーティション化、リスト・パーティション化、またはハッシュ・パーティション化を使用して、XMLType
表や、XMLType
列が含まれる表をパーティション化する場合、その表にXMLIndex
索引を作成することもできます。オプションで、索引の作成とメンテナンスが並列で実行されるようにできます。
索引作成とメンテナンスを確実に並列化するには、XMLIndex
索引を作成または変更するとき、PARALLEL
句を(オプションで)使用します。
XMLIndex
索引を作成するときにキーワードLOCAL
を使用すると、索引とその記憶域表すべてが、実表に関連してローカルに同一レベル・パーティション化されます。
キーワードLOCAL
を使用しない場合は、パーティション化された表にXMLIndex
索引を作成できません。また、コンポジット・パーティション化した表には、XMLIndex
索引を作成できません。
PARALLEL
句を使用しており、実表がパーティション化されていたり、実表で並列度が有効になっている場合は、これによりDML操作(INSERT
、UPDATE
、DELETE
)と索引DDL操作(CREATE
、ALTER
、REBUILD
)の両方のパフォーマンスを向上させることができます。
索引に並列度を指定すると、問合せサーバー・プロセスそれぞれに個別に記憶域パラメータが適用されるため、記憶域の消費も多くなります。たとえば、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)');
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 INDEX
のPARAMETERS
句またはXMLIndex
のALTER INDEX
文で使用されます。
表6-7 索引の同期化
同期化するタイミング | ASYNC句の構文 |
---|---|
常時 |
これはデフォルトの動作です。前の |
コミット時 |
|
定期的 |
|
手動、オン・デマンド |
PL/SQLプロシージャ |
ASYNC
構文のオプションのパラメータであるSTALE
は、将来に備えて用意されているものであり、明示的に指定する必要はありません。ALWAYS
が使用されていれば、値は常にFALSE
になります。それ以外の場合の値はTRUE
です。このルールに反して明示的なSTALE
値を指定すると、エラーが発生します。
例6-38では、明日から毎週月曜日の午後3時に同期化されるXMLIndex索引を作成します。
例6-39では、例6-38で作成された索引を手動で同期化します。
XMLIndex
索引の同期化が遅延されると、索引に対する最終同期化以降、実表に対して加えられたすべてのDML変更(挿入、更新、削除)は、DML操作当たり1行ずつ、保留中の表に記録されます。この表の名前は、静的なパブリック・ビューUSER_XML_INDEXES
、ALL_XML_INDEXES
、およびDBA_XML_INDEXES
のPEND_TABLE_NAME
列の値です。
この表を検証すると、指定のXMLIndex
索引を同期化させる最適な時期を決定できます。保留中の表の行数が多くなると、同期化が必要な索引も多くなります。
保留中の表のサイズが大きい場合、syncIndex
のコール時にパラメータREINDEX
をTRUE
に設定すると、例6-39に示すようにパフォーマンスを向上できます。REINDEX
がTRUE
の場合は、すべての2次索引が削除され、保留中の表データを一括ロードした後に再作成されます。
関連項目:
-
repeat_interval
の構文は、Oracle Database PL/SQLパッケージおよびタイプ・リファレンスの「カレンダ構文」の項を参照してください。 -
PL/SQLプロシージャ
DBMS_XMLINDEX.syncIndex
の詳細は、Oracle Database PL/SQLパッケージおよびタイプ・リファレンスを参照してください。
例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);
エラーORA-08181が発生した場合のXMLIndex索引の同期化
問合せを行うとエラーORA-08181が発生する場合は、問合せのXMLType
実表に対して、非構造化コンポーネントを含むXMLIndex
索引が作成されているかどうかを確認してください。その場合は、DBMS_XMLINDEX.syncIndex
を使用して、XMLIndex
索引を手動で同期化します。
これは、エラーORA-08181が次の状況で発生した場合にのみ適用されます。
- プラガブル・データベース
PDB1
で、XMLType
表または列XTABCOL
を作成し、非構造化コンポーネントが含まれるXMLIndex
索引を使用して索引付けを行った。 PDB1
をコンテナ・データベースに接続している。PDB1
を新しいプラガブル・データベースPDB2
にクローニングした。PDB2
で問合せXTABCOL
を実行すると、エラーORA-08181が発生する。
同期化しても引き続きエラーが発生する場合は、別の原因を探します。エラーORA-08181は様々な状況で発生する可能性のある一般的なエラーで、これは原因の1つにすぎません。
関連トピック
コストベース・オプティマイザに対する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);
XMLIndexに関連するデータ・ディクショナリの静的なパブリック・ビュー
標準的なデータベース索引に関する情報は、静的なパブリック・ビューUSER_INDEXES
、ALL_INDEXES
、およびDBA_INDEXES
にあります。XMLIndex
索引に関する同様の情報も、静的なパブリック・ビューUSER_XML_INDEXES
、ALL_XML_INDEXES
、およびDBA_XML_INDEXES
にあります。
表6-8で、これらの各ビューの列について説明します。
表6-8 XMLIndexの静的なパブリック・ビュー
列名 | 型 | 説明 |
---|---|---|
|
|
非同期索引の更新の仕様です。XMLIndex索引の非同期(遅延)メンテナンスを参照してください。 |
|
|
パスのサブセット化:
|
|
|
|
|
|
索引の所有者です。 |
|
|
索引のコンポーネントのタイプは、 |
|
|
索引の作成に使用された 非構造化 構造化コンポーネントが存在する場合、 |
|
|
|
|
|
最後に行われた索引の同期以降の、実表のDML操作を記録する表の名前です。XMLIndex索引の非同期(遅延)メンテナンスを参照してください。 |
|
|
索引が定義されている実表の名前です。 |
|
|
索引が定義されている実表の所有者です。 |
これらのビューでは、XMLIndex
索引に関する情報が提供されますが、XMLIndex
索引で収集される統計に関する情報を提供する静的データ・ディクショナリ・ビューはありません。この統計情報は、次のビュー間で配信されます。
-
USER_INDEXES
、ALL_INDEXES
、DBA_INDEXES
– 列LAST_ANALYZED
では、XMLIndex
索引の最終分析日が提供されます。 -
USER_TAB_STATISTICS
、ALL_TAB_STATISTICS
、DBA_TAB_STATISTICS
– 列TABLE_NAME
では、XMLIndex
索引の構造化コンポーネントおよび非構造化コンポーネントの情報が提供されます。構造化コンポーネントまたは非構造化コンポーネントの情報については、パス表またはXMLTable
表の名前をTABLE_NAME
としてそれぞれ使用して問い合せます。 -
USER_IND_STATISTICS
、ALL_IND_STATISTICS
、DBA_IND_STATISTICS
– 列INDEX_NAME
では、XMLIndex
索引の2次索引のそれぞれの情報が提供されます。指定された2次索引に関する情報については、その2次索引の名前をINDEX_NAME
として使用して問い合せます。
CREATE INDEXおよびALTER INDEXのPARAMETERS句
XMLIndex
索引の作成または変更では、多くの場合、SQL文CREATE INDEX
またはALTER INDEX
でPARAMETERS
句が使用されます。これを使用して、詳細に索引特性を指定できます。
PARAMETERS
句の1000文字の制限を回避するために、パッケージDBMS_XMLINDEX
内のPL/SQLプロシージャregisterParameter
およびmodifyParameter
を使用できます。
関連項目:
-
index_attributes
の構文は、Oracle Database SQL言語リファレンスを参照してください。 -
segment_attributes_clause
の構文は、Oracle Database SQL言語リファレンスを参照してください。 -
table_properties
の構文は、Oracle Database SQL言語リファレンスを参照してください。 -
parallel_clause
の構文は、Oracle Database SQL言語リファレンスを参照してください。 -
CREATE INDEX
の構文およびセマンティクスの追加情報は、Oracle Database SQL言語リファレンスを参照してください。 -
ALTER INDEX
の構文およびセマンティクスの追加情報は、Oracle Database SQL言語リファレンスを参照してください。 -
repeat_interval
の構文は、Oracle Database PL/SQLパッケージおよびタイプ・リファレンスの「カレンダ構文」の項を参照してください。
XMLIndexの登録済パラメータ句の使用
CREATE INDEX
またはALTER INDEX
文のPARAMETERS
句に使用する文字列値には、1000文字の制限があります。この制限を回避するには、パッケージDBMS_XMLINDEX
内のPL/SQLプロシージャregisterParameter
およびmodifyParameter
を使用できます。
これらのプロシージャごとに、(長さ制限のない)パラメータの文字列と、その文字列の登録に使用する識別子を指定します。次に索引PARAMETERS
句で、リテラル文字列ではなく、キーワードPARAM
で始まる識別子を指定します。
識別子は、CREATE INDEX
またはALTER INDEX
文で使用する前に、登録しておく必要があります。
関連項目:
CREATE INDEXおよびALTER INDEXのPARAMETERS句の構文
CREATE INDEX
およびALTER INDEX
のPARAMETERS
句の構文は、定義されています。
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関数XMLTableのXML_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 :==
XMLIndex_parameters_clauseの使用
XMLIndex
索引を作成するとき、XMLIndex_parameters_clause
がなければ、新しい索引には非構造化コンポーネントのみが含まれます。XMLIndex_parameters_clause
があってもPARAMETERS
引数が空(''
)の場合、結果は同じであり、索引には非構造化コンポーネントのみが含められます。
関連項目:
-
CREATE INDEX
のXMLIndex_parameters_clause
の使用コンテキストの詳細は、Oracle Database SQL言語リファレンスを参照してください。 -
ALTER INDEX
のXMLIndex_parameters_clause
の使用コンテキストの詳細は、Oracle Database SQL言語リファレンスを参照してください。
XMLIndex_parameterの使用
XMLIndex_parameters
を使用する場合は、特定の考慮事項が適用されます。
-
XMLIndex_parameters
では、XMLIndex_parameter_clause
を1種類当たり最大1回しか使用できません。たとえば、PATHS
句を最大で1回、path_table_clause
を最大で1回などです。 -
XMLIndex
索引を作成するとき、structured_clause
がなければ、新しい索引には非構造化コンポーネントのみが含められます。structured_clause
が存在すれば、新しい索引には構造化コンポーネントのみが含められます。
PATHS句の使用
PATHS
句を使用する場合は、特定の考慮事項が適用されます。
-
CREATE INDEX
文では、PATHS
句を最大で1回使用できます。つまり、create_index_paths_clause
の前に、PATHS
を最大で1回使用できます。 -
create_index_paths_clause
句はCREATE INDEX
でのみ、また、alter_index_paths_clause
句はALTER INDEX
でのみ使用されます。
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
を使用して作成しなおします。
pikey_clause、path_id_clauseおよびorder_key_clauseの使用
pikey_clause
、path_id_clause
およびorder_key_clause
の各句は、構文的にそれぞれ省略可能です。pikey索引は、pikey_clause
を指定しない場合でも作成されます。パスID索引または順序キー索引を作成するには、path_id_clause
またはorder_key_clause
をそれぞれ指定する必要があります。
value_clauseの使用
value_clause
を使用する場合は、特定の考慮事項が適用されます。
-
VALUE
列は、VARCHAR2(4000)
として作成されています。 -
value_clause
句がキーワードVALUE
でのみ構成される場合は、通常のデフォルト属性によって値索引が作成されます。 -
path_id_clause
句がキーワードPATH ID
でのみ構成される場合は、通常のデフォルト属性によってパスID索引が作成されます。 -
order_key_clause
句がキーワードORDER KEY
でのみ構成される場合は、通常のデフォルト属性によって順序キー索引が作成されます。
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
の場合、STALE
はFALSE
です。 -
ALWAYS
以外のASYNC
オプションの場合、STALE
はTRUE
です。
-
groups_clauseおよびalter_index_group_clauseの使用
groups_clause
句は、CREATE INDEX
(alter_index_group_clause
句のADD GROUP
の後)でのみ使用されます。alter_index_group_clause
句は、ALTER INDEX
でのみ使用されます。
XMLIndex_xmltable_clauseの使用
XMLIndex_xmltable_clause
を使用する場合は、特定の考慮事項が適用されます。
-
XMLIndex_xmltable_clause
内のXQuery_string
式では、XQuery関数ora:view
(サポート対象外)、fn:doc
またはfn:collection
を使用できません。 -
特定の
XMLIndex_xmltable_clause
にデータ型XMLType
のcolumn_clause
が複数含まれる場合、Oracle XML DBでエラーが発生します。このような2つの仮想列を定義した場合と同じ結果にするには、個別にgroup_clause
を追加する必要があります。 -
XMLIndex_xmltable_clause
ではPASSING
句はオプションです。この句が存在しない場合、次のようにXMLType
列が暗黙的に渡されます。-
パラメータ句の最初の
XMLIndex_xmltable_clause
では、索引付けされるXMLType
列が暗黙的に渡されます。(XMLType
表に索引を作成する場合、疑似列OBJECT_VALUE
が渡されます。) -
それ以降の各
XMLIndex_xmltable_clause
については、その前のXMLIndex_xmltable_clause
のVIRTUAL
XMLType
列が暗黙的に渡されます。
-
column_clauseの使用
column_clause
を使用する場合は、特定の考慮事項が適用されます。
XMLIndex
索引でXMLTable
のマルチレベル連鎖を使用する場合、あるレベルのXMLTable
表は、その前のレベルのXMLType
列に対応します。構文の説明で、キーワードVIRTUAL
はオプションとして示されています。実際には、これはXMLType
列でのみ使用され、その場合は必須です。XMLType
列以外に使用するとエラーになります。VIRTUAL
は、XMLType
列自体が生成されないことを指定します。つまり、そのデータは、対応するXMLTable
表により指定されたリレーショナル列の形式でのみ、索引に格納されます。
XML検索索引の作成
検索索引を作成するには、CREATE SEARCH INDEX
文にFOR XML
句を指定します。XML検索索引は、23cのデフォルトであるTRANSPORTABLE BINARY XML
(TBX)記憶域オプションを使用してドキュメントを格納するSYS.XMLType
データ型の列にのみ作成できます。
TBXオプションを使用して格納されていないXMLデータには、XQuery Full Text CONTEXT
索引を作成することで索引付けできます。
XML検索索引の構文
CREATE SEARCH INDEX [schema.]index ON [schema.]table(xml_column) FOR XML [LOCAL] PARAMETERS( [SEARCH_ON (TEXT | TEXT_VALUE(data_types) | VALUE(data_types))] [STORAGE storage_pref] [PREFIX_NS (prefix_ns_mapping)] [MEMORY memsize] [SYNC (MANUAL | EVERY "interval-string" | ON COMMIT)] [MAINTENANCE AUTO | MAINTENANCE MANUAL] [OPTIMIZE (MANUAL | EVERY "interval-string" | AUTO_DAILY)] ) [PARALLEL N] [UNUSABLE];
説明:
-
[schema.]index
は、作成するXML検索索引の名前を指定します。 -
[schema.]table(xml_column)
は、索引付けする表および列の名前を指定します。xml_column
は、索引が作成される列の名前です。
関連項目:
これらのパラメータの詳細は、『Oracle Textリファレンス』を参照してください。
全文問合せ用のXMLデータの索引付け
XMLデータの全文検索を行う必要がある場合は、バイナリXMLとしてXMLType
データを格納し、XQuery Full Text (XQFT)を使用することをお薦めします。これには、XML検索索引を使用します。これが、この項の内容です。
XML検索索引は、SEARCH INDEX FOR XML
構文を使用するか、XQFT対応のCONTEXT
索引を作成することで作成できます。SEARCH INDEX FOR XML
を使用してXML検索索引を作成することをお薦めします。
移植性やコードの標準化が問題にならない場合や、XMLType
データがオブジェクト・リレーショナル形式で格納されている場合は、かわりにOracle固有の全文構造体とOracle Textが提供している構文、具体的にはOracle SQL関数contains
を使用できます。
バイナリXMLとして格納されているXMLType
データに対しては、XQuery Full Text (XQFT)問合せを実行できます。SQL WHERE
句内のXMLExists
式でXQFT全文述語を使用する場合は、XML検索索引を作成する必要があります。この項では、このような索引の作成と使用について説明します。
関連トピック
関連項目:
XML検索索引の作成と使用
XQuery Full Text問合せでは、パフォーマンスを高めるためにXML検索索引を使用できます。
XML検索索引を作成するには、データベース・ロールCTXAPP
を付与されている必要があります。一般的にこのロールは、Oracle Text索引の作成、Oracle Text索引プリファレンスの設定、またはOracle Text PL/SQLパッケージの使用に必要です。
索引を作成する前に、XQuery Full Text (XQFT)対応のCONTEXT索引を作成するか、XML検索索引を作成するかを決定する必要があります。
XQFT対応のCONTEXT索引を作成する場合、Oracle Textパス・セクション・グループを作成して、そのXML_ENABLE
属性をt
に設定する必要があります。これにより、パス・セクション・グループがXML対応になります。
XML検索索引を作成する場合は、索引を利用する問合せのタイプを決定する必要があります。XMLExists演算子でXQuery Full Text述語のみを使用する場合は、索引のパラメータ文字列にSEARCH_ON TEXT
を指定します。
詳細は、「XML検索索引のプリファレンス推奨事項」の項を参照してください
XQFT対応CONTEXT索引およびXML検索索引の両方のプリファレンス推奨事項
パフォーマンスを向上させるには、Oracle Textデータ・ディクショナリ内にBASIC_STORAGE
型の索引プレファレンスを作成して、次の属性を指定します。
-
D_TABLE_CLAUSE
– XML文書の構造に関する情報が含まれている索引データ表$D
の列DOC
に対して、SECUREFILE
記憶域を指定します。キャッシュおよび圧縮レベル(MEDIUM)を指定します。 -
I_TABLE_CLAUSE
– 全文トークンと索引付けされた文書でのその出現に関する情報が含まれている索引データ表$I
の列TOKEN_INFO
に対して、SECUREFILE
記憶域を指定します。キャッシュを指定します(ただし圧縮は不要)。 -
STAGE_ITAB
- ステージング表機能を有効にするには、TRUE
を指定します。ステージング表は、特定の行のしきい値に達した後にのみステージング表の内容を索引とマージすることで、メンテナンス操作後の索引の断片化の量を減らします。ステージング表のデータは依然として索引の一部です。 -
STAGE_ITAB_MAX_ROWS
-10000
以上の値を指定します。この値は、DMLによって索引が保持される頻度に応じてチューニングする必要があります。値を大きくすると、ステージング表の内容がマージされる頻度は低くなりますが、ステージング表は断片化されます。 -
STAGE_ITAB_AUTO_OPT
- ステージング表のマージをバックグラウンドで実行できるようにするには、TRUE
を指定します。 -
STAGE_ITAB_PARALLLE
- ステージング表をマージするときに並列度を指定します。デフォルトでは、マージ操作では並列度4が使用されます。
これについては例6-41で、XML Schemaに基づかないXMLType
表po_binxml
(標準のデータベース・スキーマOE
内の表purchaseorder
と同じデータを持つ)を使用して説明します。
XQFT対応CONTEXT索引およびXML検索索引は、デフォルトでシステム制御方式でバックグラウンドで同期化されます。索引の同期化は、プロシージャCTX_DDL.SYNC_INDEX
を起動してオンデマンドでトリガーすることもできます。
索引の同期化は、トランザクションのコミット時または少なくとも時間間隔の経過後に定期的に行われるようにチューニングできます。索引の同期化の方法を変更するには、次のようにSYNC
オプションを指定します:
-
SYNC (ON COMMIT)
– 索引はトランザクションのコミット中に同期化されます。 -
SYNC (EVERY "interval information")
– 索引付けが保留中のドキュメントがあるかどうかを確認することで、索引はバックグラウンドで定期的に同期化されます。
索引プレファレンスBASIC_STORAGE
は、Oracle Text索引を構成するデータベース表および索引に対する表領域および作成パラメータを指定します。
関連項目:
-
索引の同期化とメンテナンスの詳細は、『Oracle Textリファレンス』を参照してください
-
セクション・グループの詳細は、Oracle Textリファレンスを参照してください。
-
プロシージャ
CTX_DDL.set_sec_grp_attr
の詳細は、Oracle Textリファレンスを参照してください。 -
プロシージャ
CTX_DDL.create_preference
の詳細は、Oracle Textリファレンスを参照してください。 -
プロシージャ
CTX_DDL.set_attribute
の詳細は、Oracle Textリファレンスを参照してください。 -
プレファレンス
BASIC_STORAGE
、D_TABLE_CLAUSE
およびI_TABLE_CLAUSE
の詳細は、Oracle Textリファレンスを参照してください。
例6-45では、データ問合せを実行して、テキストにBig
とStreet
の両方がこの順序で含まれるDescription
要素を取得します。
例6-46は、索引po_ctx_idx
の取得を指示する、問合せの実行計画を示しています。
XML検索索引のプリファレンス推奨事項
XML検索索引は、次のような特定の用途に作成できます:
-
XQuery Full Text (XQFT)問合せにのみ回答します。
-
数値、日時または文字列型指定されたフィールドを介して、範囲検索問合せのみに回答します。
-
XQuery Full Text (XQFT)問合せと範囲検索問合せの両方の混在に対して回答します。
どの索引付けプリファレンスを有効にするかを指定するには、SEARCH_ON
句を使用します:
-
SEARCH_ON TEXT
- 全文検索に対してのみ索引付けを有効にします。 -
SEARCH_ON VALUE
- 特定のデータ型に対する範囲検索に対してのみ索引付けを有効にします。VALUE
を指定する場合は、少なくとも1つのデータ型(NUMBER
、BINARY_DOUBLE
、VARCHAR2
またはTIMESTAMP
)を使用する必要があります。 -
SEARCH_ON TEXT_VALUE
- 全文検索と範囲検索の両方で索引付けを有効にします。TEXT_VALUE
を指定する場合は、少なくとも1つのデータ型(NUMBER
、BINARY_DOUBLE
、VARCHAR2
またはTIMESTAMP
)を使用する必要があります。
XML検索索引を作成する場合、STORAGE
プリファレンスが指定されていないと、Oracle Textの記憶域プリファレンスの一部がデフォルトで設定されます。デフォルトでは、次のプリファレンスが有効になります:
-
STAGE_ITAB
- ステージング表が有効になります。 -
STAGE_ITAB_MAX_ROWS
- ステージング表をマージするためのしきい値は10000行に設定されます。 -
STAGE_ITAB_AUTO_OPT
- ステージング表のマージはバックグラウンドで実行されます。
例6-41 XQFT対応CONTEXT索引の作成
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)'); CTX_DDL.set_attribute('mypref', 'STAGE_ITAB', 'TRUE'); CTX_DDL.set_attribute('mypref', 'STAGE_ITAB_MAX_ROWS', '10000'); CTX_DDL.set_attribute('mypref', 'STAGE_ITAB_AUTO_OPT', 'TRUE'); CTX_DDL.set_attribute('mypref', 'STAGE_ITAB_PARALLEL', '4'); 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 (XQFT)ワークロードのXML検索索引の作成
CREATE TABLE po_binxml (doc SYS.XMLTYPE) XMLTYPE doc STORE AS TRANSPORTABLE BINARY XML; BEGIN 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)'); CTX_DDL.set_attribute('mypref', 'STAGE_ITAB', 'TRUE'); CTX_DDL.set_attribute('mypref', 'STAGE_ITAB_MAX_ROWS', '10000'); CTX_DDL.set_attribute('mypref', 'STAGE_ITAB_AUTO_OPT', 'TRUE'); CTX_DDL.set_attribute('mypref', 'STAGE_ITAB_PARALLEL', '4'); END; / CREATE SEARCH INDEX po_ctx_idx ON po_binxml (doc) FOR XML PARAMETERS ('storage mypref SEARCH_ON TEXT');
例6-43 数値および文字列に対する範囲検索問合せ用のXML検索索引の作成
CREATE SEARCH INDEX po_ctx_idx ON po_binxml (OBJECT_VALUE) FOR XML PARAMETERS ('storage mypref SEARCH_ON VALUE(BINARY_DOUBLE, VARCHAR2)');
例6-44 XQuery Full Text (XQFT)と数値、日時およびタイムスタンプ値の範囲検索の両方のXML検索索引の作成
CREATE SEARCH INDEX po_ctx_idx ON po_binxml (OBJECT_VALUE) FOR XML PARAMETERS ('storage mypref SEARCH_ON VALUE(BINARY_DOUBLE, VARCHAR2, TIMESTAMP)');
例6-45 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-46 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.
XML検索索引を取得できない場合の対処方法
XQuery Full Text述語に対して索引を取得できない場合の対処方法
特定の条件が確実に満たされるように問合せを変更することで、評価によって索引が取得されるようにできます。
SQL WHERE
句内のXMLExists
式でXQuery全文述語を使用しながら、XQFT対応CONTEXT索引または全文検索対応のXML検索索引を作成しなかったり、なんらかの理由でその索引を使用できない場合には、コンパイル時エラーORA-18177が発生します。
エラーが発生した場合、実行計画では、索引の取得は指示されません。計画には、操作DOMAIN INDEX
の後に索引の名前は表示されません。
この場合は、索引を使用できるように問合せを変更してください。取得する索引では、次の条件の両方を満たす必要があります。
-
検索コンテキストのXMLノードを計算する式は、ステップがforward軸およびdescendent軸のみに沿ったXPath式にする必要があります。
-
SQL/XML関数
XMLExists
のPASSING
句にSQL式として渡すことのできるXMLType
インスタンスは1つのみで、同じ句内に含まれるその他の非XMLType
SQL式はすべて、組込みSQLデータ型のコンパイル時定数、またはこのようなデータ型のインスタンスにバインドされているバインド変数のいずれかである必要があります。
範囲検索問合せ述語に対して索引を取得できない場合の対処方法
SQLのwhere句内のXMLExists
式で関係演算子(>
、<
、<=
、>=
または=
)を使用して範囲検索述語を使用しながら、関係するデータ型を索引付けしたXML検索索引を作成しない場合は、XMLExists
述語では索引スキャンのかわりに機能評価が使用されます。
XQuery Full Text (XQFT)式で索引が取得される条件に加えて、索引が取得されるには、次の条件を適用する必要があります。
-
比較値は、コンパイル時定数またはカーソルの実行前にバインドされたバインド変数である必要があります。
-
コンパイル時定数またはバインド変数のデータ型は、索引で有効にする必要があります。
-
リレーショナル述語を
!=
にすることはできません。 -
NOT()
を使用して述語を否定することはできません。
索引に対して正しいデータ型が選択されるように、xs:double
、xs:decimal
、xs:dateTime
などのデータ型コンストラクタを使用して、正しいデータ型が推測されるようにすることができます。
前述の考慮事項に加えて、XML検索索引と同じ列に構造化XMLIndexもある場合、構造化XMLIndexの使用はXML検索索引よりも優先されます。この動作は、ora:use_xmltext_idx pragma
を使用してXML検索索引が構造化XML索引よりも優先的に取得されるように強制することでオーバーライドできます。プラグマora:use_xmltext_idx
の使用方法の詳細は、「プラグマora:use_xmltext_idx: XML検索索引の強制的な使用」を参照してください。
例6-47 XML検索索引によって回答されたXMLExists述語の範囲検索問合せ
SELECT XMLQuery('for $i in /PurchaseOrder return <Details>{$i/User}{$i/Reference}</Details>' PASSING doc RETURNING CONTENT) FROM xtab WHERE XMLExists('/PurchaseOrder/LineItems/LineItem/Part[UnitPrice < 15.0]' PASSING doc);
この問合せは、$15.00より安い1つ以上の品目を含む購買オーダーのユーザーおよび参照を返します。
例6-48 XML検索索引によって回答されたXMLExists述語の範囲検索問合せの実行計画
---------------------------------------------- | Id | Operation | Name | ---------------------------------------------- | 0 | SELECT STATEMENT | | | 1 | SORT AGGREGATE | | |* 2 | FILTER | | | 3 | FAST DUAL | | | 4 | NESTED LOOPS | | | 5 | TABLE ACCESS BY INDEX ROWID| XTAB | |* 6 | DOMAIN INDEX | XSIDX | | 7 | XPATH EVALUATION | | ---------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter(:B1 IS NOT NULL) 6 - access("CTXSYS"."CONTAINS"(SYS_MAKEXML(131072,"SYS_NC00002$"),'<query>< textquery grammar="CONTEXT" lang="english">sdata(FNUM_284549FF0C91A6F6A8AABBEE 2B5798E5_UnitPrice < 15.0 )</textquery></query>')>0)
プラグマ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-49に、これを示します。
問合せの全文条件が、XML Schema型と型指定された操作に依存することを想定していたユーザーは、発生したエラーによってこれを意識するようになります。
型に依存する条件を使用するためには、関連するXQuery式を明示的に適切な型にキャストする必要があります。Oracle XML DBでは、XML Schemaを使用して暗黙的な型キャストを実行することはありません。型キャストを適切に実行できないと、予期しない結果が生じる可能性があります。
例6-50は、適切な条件が評価されるように型キャストを明示的に指定した、XML Schemaに基づくデータの問合せを示しています。
ただし、XQuery Full Text式を使用する場合は通常、XML Schemaに基づくデータを扱うときでも、型指定されたデータは含めません。型指定されたデータを条件で使用する場合は、適切な型にキャストする必要があるので注意してください。
つまり、型指定されたデータが問合せに含まれていないことがわかっている、または特定の型指定されたデータを型指定されていないデータとして扱っても問題ない、あるいは型指定が必要なデータは明示的に型キャストする場合は、問合せでOracle XQueryプラグマora:no_schema
を使用すれば、エラーの発生を防ぎつつ、XML検索索引を使用して問合せを評価できます。
例6-49 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-50 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);
プラグマ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-51の問合せでは、プラグマora:use_xmltext_idx
の使用方法を示しています。XMLExists
の最初の句にのみ全文条件が使用されています。プラグマが指定されているので、全文索引(po_ctx_idx
、**INTERNAL XREF ERROR**で作成)は、両方のXMLExists
句で使用されます。
例6-51 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);
Oracle Text索引の使用からXML検索索引への移行
バイナリXMLとして格納されているXMLType
データに対するレガシー問合せで、SQL関数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
)が使用されていました。
これを使用しているレガシー・コードがある場合は、そのコードを移行してXQFTを使用することをお薦めします。この項では、問合せで使用されているCONTAINS
を置き換える場合に使用できるXQFTの構造体について説明します。
Oracle Text索引のこのような使用方法は、XQuery Full Text (XQFT)対応CONTEXT索引またはXML検索索引のいずれかで置換することもできます。HASPATH
を使用する問合せを簡単なXQuery式を使用する問合せで置き換えるには、Oracle XQueryプラグマora:use_xmltext_idx
を使用して、XML検索索引を取得するように指定します。この項では、これについても説明します。
表6-9に、Oracle固有の構造体を使用する一般的な問合せからXQuery Full Textを使用する問合せへのマッピングを示します。
表6-9 Oracle固有のXML問合せのXQuery Full Textへの移行
元の例 | 置換後の例 |
---|---|
|
または、データがXML Schemaに基づく場合:
|
|
または、データがXML Schemaに基づく場合:
|
|
|
|
|
|
|
|
|
|
|
(適用なし – Oracle Text問合せはXML名前空間に非対応) |
|
脚注3
パスのテストには述語式を含めることができ、それは元の問合せ(HASPATH
を使用)でも置換後の問合せでも同じです。たとえば: /PurchaseOrder/LineItems/LineItem/Part[@Id < "31415927"]
オブジェクト・リレーショナル形式で格納されたXMLTypeデータの索引付け
XMLノードに対応する基礎となるデータベース列に対してBツリー索引を作成することで、オブジェクト・リレーショナル形式で格納されたXMLType
データを効果的に索引付けできます。
索引付けされるデータが単一の場合、つまりXMLインスタンス文書で一度のみ発生する可能性がある場合、表面的上ファンクション索引を作成するショートカットを使用できます。この場合、索引を定義する式はファンクション・アプリケーションで、単一データをターゲットとするXPath式の引数を使用します。ショートカットはXMLQuery
に適用されるXMLCast
に対して定義され、もう1つのショートカットはOracle SQL関数extractValue
に対して定義されます(非推奨)。
多くの場合、Oracle XML DBでは、基礎となるオブジェクト・リレーショナル表または列に対して適切な索引が自動的に作成されますが、CREATE INDEX文が示すように、ターゲットとなるXMLType
データに対して、ファンクション索引は作成されません
。
extractValue
ショートカットの場合、作成される索引はBツリー索引です。XMLQuery
に適用されるXMLCast
の場合、作成される索引は、ファンクション式から得られるスカラー値に対するファンクション索引です。
索引付けされるデータがコレクションの場合、このようなショートカットを使用できません。手動でBツリー索引を作成する必要があります。
繰り返し使用しないテキスト・ノードまたは属性値の索引付け
サンプル・データベース・スキーマOE
の表purchaseorder
はオブジェクト・リレーショナルに格納されます。各発注書には単一のReference
要素が含まれます。つまりこの要素は単一です。したがって、ショートカットを使用して、基礎となるオブジェクト・リレーショナル・データに索引を作成できます。
例6-52に、Reference
要素のテキスト・コンテンツをターゲットとし、XMLQuery
に適用されるXMLCast
を使用して、表面上ファンクション索引を作成しようとするCREATE INDEX
文を示します。(この要素のコンテンツはテキストのみのため、要素をターゲットにすることは、XPathノード・テストtext()
を使用してテキスト・ノードをターゲットにすることと同じです。)
例6-53は、同じデータをターゲットにし、Oracle SQL関数extractValue
(非推奨)を使用して表面上ファンクション索引を作成します。
実際、例6-52と例6-53では、ターゲットとなるXMLType
データに対してファンクション索引は作成されません。かわりに、Oracle XML DBによってCREATE INDEX
文がリライトされ、基礎となるスカラー・データに対して索引が作成されます。
これらのショートカットのいずれかを使用するとき、CREATE INDEX
文は前述のように基礎となるスカラー・データ上に索引を作成できない場合があります。そのかわり、実際には参照されるXMLType
データにファンクション索引を作成します。(これは索引の値がスカラーである場合でも当てはまります)。
このような場合は、索引を削除し、同じXPathをターゲットとする構造化コンポーネントを含むXMLIndex
索引をかわりに作成します。一般的に、XMLType
データに対してはファンクション索引を使用しないことをお薦めします。
これは使用される格納方法にかかわらず、XMLType
データの一般的なルールです。ファンクション索引のかわりに構造化コンポーネントでXMLIndex
を使用します。このルールはOracle Database 11gリリース 2 (11.2)から適用されます。このルールを守ることにより、ファンクション索引のメンテナンス操作に関連するオーバーヘッドを軽減し、オプティマイザで索引を適切に選択できる状況が増えます。
例6-52 単一の要素で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-53 単一の要素でEXTRACTVALUEを使用したCREATE INDEX
CREATE INDEX po_reference_ix ON purchaseorder (extractValue(OBJECT_VALUE, '/PurchaseOrder/Reference'));
関連トピック
繰り返し使用する(コレクション)要素の索引付け
オブジェクト・リレーショナル形式で格納されたXMLType
データでは、コレクションはXMLType
インスタンスのOrdered Collection Table (OCT)として格納されるため、メンバーに直接アクセスできます。オブジェクト・リレーショナル記憶域は、XMLデータのファイングレイン構造を直接反映するため、各コレクション・メンバーをターゲットとする索引を作成できます。
このような索引は、手動で作成する必要があります。Oracle SQL関数extractValue
(非推奨)に対して表面上ファンクション索引を作成する場合に、Bツリー索引を自動的に作成する専用の機能は、コレクションに適用されません(extractValue
に渡されるXPath式は、単一要素をターゲットにする必要があります)。
コレクションに対してBツリー索引を作成するには、コレクションの管理に使用するSQLオブジェクトの構造を理解する必要があります。その情報に基づき、従来のオブジェクト・リレーショナルSQLコードを使用して、適切なSQLオブジェクト属性に対して索引を直接作成できます。この方法の例は、ガイドライン: Ordered Collection Tableに対する索引の作成を参照してください。
脚注の説明
脚注1:オブジェクト・リレーショナル形式で格納されているXMLType
データについては、オブジェクト・リレーショナル形式で格納されたXMLTypeデータの索引付けを参照してください。データの構造化が高度に進んでいる場合、または索引の作成時点で問合せが既知でない場合には、この方法が適している可能性があります。
脚注2:
実際のパス表の実装は多少異なることがあります。