XMLEXISTS述語にXQuery式を指定してXMLデータを検索するとき、XQuery式の指定形式が特定の条件を満たしていれば、XMLデータの検索が速くなる場合があります。これはXQuery式の指定形式に応じて、XMLデータの検索に利用するデータモデルが変化するためです。
以下に示すようなXMLデータの検索を行う際、XQuery式の指定形式が特定の条件に一致していれば、XQueryの検索性能が向上する場合があります。
検索内容 | 説明 |
---|---|
あるノードが存在するかで検索する | 検索条件に指定した名前のノードが、XMLデータの中に存在しているかどうかについて検索を行います。 |
あるエレメントノードの属性の値で検索する | 検索条件に指定した文字列と、XMLデータ内のあるエレメントノードの属性の値を比較することで検索を行います。 |
あるエレメントノードの内容で検索する | 検索条件に指定した文字列と、XMLデータ内のあるエレメントノードの内容を比較することで検索を行います。 |
高速検索を可能にするXQuery式
XQueryの検索性能を向上させるためには、以下に示す文法規則に従う必要があります。
参照
文字列リテラルおよびQNameの指定形式については、“XQueryリファレンス”の“リテラル”または“名前(QName)”を参照してください。
XQuery式の最上位には、パス式のように区切り記号“/”または“//”を繰り返し指定することができません。
比較式の右辺には文字列リテラルのみを指定することができます。数値リテラルを指定することはできません。
文字列リテラルに既定義エンティティー参照を指定することはできません。
XQuery式のパス式は、以下の条件をすべて満たしている必要があります。
“*”または“@*”の直前に“//”が指定されていない。
“*”または“@*”の直後に“//”が指定されていない。
“QName”が少なくとも1つ指定されている。
述語の直前の式にはエレメントノードの名前(“QName”)が指定されている。
ただしルートノードの場合だけは、述語の直前でも“*”が指定できる。
比較式の左辺のパス式の末尾には、“text()”、“@QName”または“@*”が指定されている。
比較演算子に“<”、“<=”、“>”、“>=”が指定されている場合には、比較式の左辺のパス式の末尾に“//text()”、“*/text()”または“@*”が指定されていない。
ここでは、この文法規則に従って高速検索可能なXQuery式を指定するための基本的な考え方について説明します。なお、本節で利用する検索対象のXMLデータは以下のとおりです。
<A> |
高速なXQuery検索においては、検索条件の指定箇所が、ルートノード名以外はすべて述語内に指定されていなければなりません。
例えば、ルートノードAの子エレメントノードBの子エレメントノードCが存在しているかどうかでXMLデータを検索したい場合、例1や例2のXQuery式のように“/A”の後に“/B”が指定されていると、高速検索はできません。しかし例3のXQuery式ように“/A”の後に“[”を指定すれば、ルートノード名以外の検索条件が述語内に指定されていることになり、高速検索が可能になります。
SELECT XMLデータ列 FROM S1.T1 WHERE XMLEXISTS('/A/B/C' PASSING XMLデータ列)
SELECT XMLデータ列 FROM S1.T1 WHERE XMLEXISTS('/A/B[C]' PASSING XMLデータ列)
SELECT XMLデータ列 FROM S1.T1 WHERE XMLEXISTS('/A[B/C]' PASSING XMLデータ列)
高速なXQuery検索においては、XMLデータの属性値または内容を文字列で比較することはできますが、数値で比較することはできません。そのため、数値と文字列で比較結果が同じであれば、文字列で比較する方がXQuery検索を高速化できます。
例えば、例4と例5のXQuery式は、検索対象のXMLデータに対して同じ結果を返すため、数値で比較している例4よりも文字列で比較している例5のXQuery式を指定した方が、高速にXMLデータを検索できます。
これに対し、例6と例7のXQuery式は、検索対象のXMLデータに対して異なる結果を返します。例6の場合は、XMLデータの属性c_idの値“005”は数値5として比較されるため、検索条件は一致します。しかし、例7の場合は、XMLデータの属性c_idの値“005”は文字列として比較されるため、検索条件の文字列“5”とは一致しません。そのため、例6の検索を高速化するためには、検索対象のXMLデータの形式に合わせて、例8のようなXQuery式を指定する必要があります。
属性b_idの値を数値123で検索
SELECT XMLデータ列 FROM S1.T1 WHERE XMLEXISTS('/A[B/@b_id=123]' PASSING XMLデータ列)
属性b_idの値を文字列“123”で検索
SELECT XMLデータ列 FROM S1.T1 WHERE XMLEXISTS('/A[B/@b_id="123"]' PASSING XMLデータ列)
属性c_idの値を数値5で検索
SELECT XMLデータ列 FROM S1.T1 WHERE XMLEXISTS('/A[B/C/@c_id=5]' PASSING XMLデータ列)
属性c_idの値を文字列“5”で検索
SELECT XMLデータ列 FROM S1.T1 WHERE XMLEXISTS('/A[B/C/@c_id="5"]' PASSING XMLデータ列)
属性c_idの値を文字列“005”で検索
SELECT XMLデータ列 FROM S1.T1 WHERE XMLEXISTS('/A[B/C/@c_id="005"]' PASSING XMLデータ列)
前述した(1)と(2)の考え方で、基本となるXQuery式の指定内容が決定したら、最後にその指定内容が文法規則に合致しているかどうかを確認します。指定内容が上述の文法規則に合致していれば、XQuery検索は高速になりますが、合致していなければXQuery検索は高速になりません。
例えば、以下のような検索条件でXMLデータを検索する場合、高速検索可能なXQuery式の指定内容は前述した(1)~(3)の考え方で決定します。
・ルートノードAの子エレメントノードBの属性b_idの値が123である。 ・ルートノードBの子エレメントノードCの内容が“test”である。
まず、上記の検索条件を満たすXQuery式として例9のようなXQuery式が考えられます。例9のXQuery式に対して、(1)で説明した考え方を適用すると、例10のようなXQuery式に変換できます。さらに例10のXQuery式に対して、(2)で説明した考え方を適用すると、例11のようなXQuery式に変換できます。最後に例11のXQuery式に対して、(3)で説明した考え方を適用し、比較式の左辺にパス式、右辺に文字列リテラルを指定すると、例12のようなXQuery式に変換できます。例12のXQuery式であれば高速なXQuery検索が可能です。
検索条件より作成
SELECT XMLデータ列 FROM S1.T1 WHERE XMLEXISTS('/A/B[@b_id=123 and "test"=C/text()]' PASSING XMLデータ列)
(1)の考え方を適用
SELECT XMLデータ列 FROM S1.T1 WHERE XMLEXISTS('/A[B/@b_id=123 and "test"=B/C/text()]' PASSING XMLデータ列)
(2)の考え方を適用
SELECT XMLデータ列 FROM S1.T1 WHERE XMLEXISTS('/A[B/@b_id="123" and "test"=B/C/text()]' PASSING XMLデータ列)
(3)の考え方を適用
SELECT XMLデータ列 FROM S1.T1 WHERE XMLEXISTS('/A[B/@b_id="123" and B/C/text()="test"]' PASSING XMLデータ列)