XML データ型のパフォーマンス最適化

Microsoft Corporation

October 2003

概要 : 本書では、Microsoft® SQL Server™ の最新バージョンである SQL Server "Yukon" の XML データ型のクエリと変更のパフォーマンスを向上するためのいくつかの技法について説明します。 本書の最も重要な点を理解するには、SQL Server との関連で XML 機能に精通している必要があります。

対象 :
    SQL Server "Yukon"

目次

はじめに
推奨する最適化

はじめに

Microsoft SQL Server "Yukon" では、XML データ処理が幅広くサポートされます。 XML の値はネイティブに XML データ型の列に保存できます。この列には、XML スキーマ名前空間に応じて型を指定することも、指定しないでおくこともできます。 XML 列にはインデックスを設定できます。 さらに、XQuery、および XQuery をデータ変更用に拡張した XML DML により、きめの細かいデータ操作がサポートされます。

SQL Server 2000 および SQLXML Web Release では、強力な XML データ管理機能が提供されています。 SQL Server "Yukon" でも、これらの機能が引き続き拡張されています。 この管理機能の主眼は、リレーショナル データと XML データのマッピングです。したがって、注釈付き XSD (Annotated XSD; AXSD) を使用してリレーショナル データの XML ビューを定義できる、XML 主体のアプローチが実現されます。 このようなビューでは、一括読み込み、クエリ、および更新の機能がサポートされます。 他のデータ管理機能として、Transact-SQL 拡張機能でリレーショナル クエリの結果を XML にマッピングする機能や XML でリレーショナル ビューを生成する機能があります。 SQL Server "Yukon" のネイティブな XML サポートと併せて、半構造化された状態のデータや、構造化されていないデータを管理する強力なアプリケーションを開発できます。

本書では、XML データ型のクエリおよびデータ変更を最適化するための提案を提供しています (関連するホワイト ペーパーでは、XML のデータ モデリングと使用法のガイドラインを示しています)。 本書の内容はまだ十分ではありません。そのため、本書は定期的に更新され、パフォーマンスの最適化に関する提案をさらに追加する予定です。 提案は、コード サンプルを使用して説明します。

XML ビューの最適化に関するテクノロジについては、MSDN Library の「SQLXML パフォーマンスの最適化」を参照してください。

推奨する最適化

存在の確認に exist() メソッドを使用する

パフォーマンスを向上するために、可能であれば、value() メソッドではなく、XML データ型の exist() 関数を使用します。 XQuery 式で sql:variable() および sql:column() を使用する場合でも、exist() 関数では、value() 関数よりも効率的に XML インデックスを使用できます。

たとえば、次のクエリを考えてみましょう。このクエリでは、exist() 関数を使用して「Database Theory」というタイトルの書籍を取得します。

SELECT * 
FROM   T 
AND    xCol::exist('/book[title="Database Theory"]) =1

XML インデックスを使用して、値 (この例では "Database Theory") の XML インデックス照合を含む、パス式 (/book[title="Database Theory"]) を評価すると、XML 列のすべての XML 値でパス式を評価するよりも行を修飾する方がより適切な選択になります。

次のように、value() 関数を使用してクエリを取得するとします。

SELECT * 
FROM   T 
AND    xCol::value('/book/title', 'varchar(50)') = 
 'Database Theory'

この場合、最初にすべての書籍タイトルが評価され、その後、"Database Theory" というフィルタが適用されます。 "Database Theory" という値は XML インデックス照合では使用されないので、この関数は、あまり効率的にクエリを実行しません。

型が指定されていない XML のテキストの集計

パス式の述語 (特に、[.="Database Theory"] 型および [fn:string()="Database Theory"] 型の述語) では、コンテキスト ノードでのテキストの集計が必要になります。 コンテキストのコンテンツにテキスト ノードが 1 つしかない場合でも、型が指定されていない XML インスタンスのこの集計には時間がかかることがあります。 このような場合、テキスト ノードの値と比較すると、より効率的に集計を実行できます。 たとえば、型が指定されていないドキュメント上に次のようなクエリがあるとします。

/book/title[.="Database Theory"]

または

/book/title[fn:string()="Database Theory"]

この場合、title 要素にあるすべてのテキスト ノードを集計する必要があります。 この要素では、検索文字列の XML インデックス照合が禁止されます。 テキスト ノードが 1 つしか存在しないことがわかっている場合は、次のように、より効率的にクエリを記述できます。

/book/title[text()="Database Theory"]

この場合は、値 "Database Theory" の XML インデックス照合が発生することがあります。

エンジンは、XML に型が指定されている場合、関連する XML スキーマを使用してこのことを推測できるので、XML インデックスを使用できます。

XQuery 式または XML DML 式の自動パラメータ化

XQuery 式および XML DML 式では、自動パラメータ化が行われません。 したがって、2 つの XQuery 式でパラメータの値のみが異なる場合は、動的な SQL ステートメントを使用する必要があります。 ただし、XQuery 式または XML DML 式を自動パラメータ化するために、sql:column() または sql:variable() を使用できます。

たとえば、次のストアド プロシージャは、ストアド プロシージャの引数に指定されているセクション番号の付いたセクションをドキュメント内で検索します。

CREATE PROC sp_myProc
   @num INT
AS
   SELECT * 
   FROM  XmlTable 
   WHERE 1= xCol::exist('//sec[@secId = sql:variable(@num)])'

ADO または OLEDB では、@num の入力値をパラメータにバインドします。 @num の別の値にバインドすると、クエリは再コンパイルされません。 sql:column() を使用する場合も、同様の結果になります。

次の例では、Microsoft Visual Basic® .NET コードを使用して、パラメータをバインドしているストアド プロシージャを呼び出す方法を示しています。

'myConn is the connectionSqlCommand cmd = New SqlCommand("myProc", myConn)
cmd.CommandType = CommandType.StoredProcedure
'Parameter binding
Dim myParm As SqlParameter = 
cmd.Parameters.Add("@num", SqlDbType.Int)
myParm.Direction = ParameterDirection.Input
myParm.value = 2
'Invoke the stored procedure
SqlDataReader myReader = cmd.ExecuteReader()
'Invoke the stored procedure a second time
myParm.value = 4
SqlDataReader myReader = cmd.ExecuteReader()

詳細については、Microsoft Visual Studio® .NET の製品ドキュメントを参照してください。

大文字と小文字を区別する照合順序

XQuery 文字列の操作および比較で大文字と小文字を区別する場合は、大文字と小文字を区別する照合順序を使用する必要があります。