プライマリ XML インデックス

プライマリ XML インデックスにより、XML 列に保存されている XML インスタンスのすべてのタグ、値、およびパスにインデックスが設定されます。プライマリ XML インデックスを作成するには、XML 列があるテーブルの主キーにクラスタ化インデックスが作成されている必要があります。SQL Server はこの主キーを使用して、プライマリ XML インデックスの行を、XML 列を含むテーブルの行に関連付けます。

プライマリ XML インデックスは、xml データ型列内の XML BLOB の細分化された永続化表現です。インデックスでは、列内の XML BLOB (バイナリ ラージ オブジェクト) ごとに、数行のデータ行が作成されます。インデックス内の行数は、XML バイナリ ラージ オブジェクトのノード数とほぼ等しくなります。クエリで完全な XML インスタンスを取得する場合は、SQL Server によって XML 列からインスタンスが返されます。XML インスタンス内でクエリを実行するときはプライマリ XML インデックスが使用され、インデックス自体によってスカラ値または XML サブツリーが返すことができます。

各行には、次のノード情報が格納されます。

  • 要素名、属性名などのタグ名。

  • ノード値。

  • 要素ノード、属性ノード、テキスト ノードなどのノードの型。

  • ドキュメント内の表示順情報。内部ノード識別子によって表現されます。

  • 各ノードから XML ツリーのルートまでのパス。クエリ内のパス式ではこの列を検索します。

  • ベース テーブルの主キー。ベース テーブルとの逆結合のため、ベース テーブルの主キーがプライマリ XML インデックスにコピーされます。ベース テーブルの主キーの最大列数は 15 です。

このノード情報は、指定されたクエリに対して XML の結果を評価し構築するために使用されます。最適化のために、タグ名とノード型の情報は整数値でエンコードされるので、パス列でも同じエンコードを使用します。また、パスのサフィックスが既知の場合にのみパスを照合できるように、パスは逆の順序で格納されます。次に例を示します。

  • //ContactRecord/PhoneNumber : 最後の 2 つのロケーション ステップだけが既知です。

または

  • /Book/*/Title : 式の中間でワイルドカード文字 (*) が指定されています。

xml データ型のメソッドに関係するクエリの場合、クエリ プロセッサでプライマリ XML インデックスが使用され、スカラ値またはプライマリ XML インデックス自体の XML サブツリーのどちらかが返されます (このプライマリ XML インデックスには XML インスタンスの再構築に必要なすべての情報が格納されています)。

たとえば、次のクエリからは ProductModel テーブルの CatalogDescriptionxml 型の列に格納された集計情報が返されます。このクエリでは、カタログの説明に <Features> の説明も含まれている製品モデルに限り <Summary> 情報が返されます。

WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' AS "PD")

SELECT CatalogDescription.query('
  /PD:ProductDescription/PD:Summary
') as Result
FROM Production.ProductModel
WHERE CatalogDescription.exist ('/PD:ProductDescription/PD:Features') = 1

プライマリ XML インデックスでは、ベース テーブルの各 XML バイナリ ラージ オブジェクト インスタンスを細分化するのではなく、各 XML バイナリ ラージ オブジェクトに対応するインデックスの行が exist() メソッドで指定された式に対して順番に検索されます。インデックスのパス列にそのパスが見つかると、プライマリ XML インデックスから <Summary> 要素とそのサブツリーが共に取得され、query() メソッドの結果として XML バイナリ ラージ オブジェクトに変換されます。

XML インスタンス全体を取得するときには、プライマリ XML インデックスが使用されないことに注意してください。たとえば、次のクエリでは、特定の製品モデルの製造手順を説明する XML インスタンス全体をテーブルから取得します。

USE AdventureWorks;

SELECT Instructions
FROM Production.ProductModel 
WHERE ProductModelID=7;