10,000レコードのテーブルのXMLタイプ列にこのようなXML階層があります-
<Root>
<Elem1>
<Parent1>
<Separator>
<Child1/>
</Separator>
</Parent1>
</Elem1>
</Root>
私はこのようなクエリを持っています-
DECLARE @Root VARCHAR(50)
DECLARE @Entity VARCHAR(50)
DECLARE @ParentNode VARCHAR(50)
DECLARE @Separator VARCHAR(50)
DECLARE @ChildNode VARCHAR(50)
SET @Root = 'Root'
SET @Entity = 'Elem1'
SET @ParentNode = 'Parent1'
SET @Separator = 'separator'
SET @ChildNode = 'Child1'
select Parent.P.value('.', 'varchar(max)') as MyValue,
T.uniqueId, T.XMLCol
from [XMLTable] as T
cross apply
(SELECT
XMLTable.XMLCol.query('(/*[local-name()=sql:variable("@Root")]/*[local-name(.)=sql:variable("@Entity")]/*[local-name(.)=sql:variable("@ParentNode")]/*[local-name(.)=sql:variable("@Separator")]/*[local-name(.)=sql:variable("@ChildNode")])[1]'
) as Parent(P)
このクエリをさらに最適化するにはどうすればよいですか。現在、2秒かかりますが、さらに内部結合を行うと、合計で時間がかかります。XML列にPRIMARYインデックスを作成しようとしましたが、時間がかかります。
編集-変数を使用する代わりにパスをハードコーディングすると、1秒もかかりません。しかし、私はそれをテーブル値関数に入れたいのですが、パスをハードコーディングできませんか?
編集-解決策
select x.value('(Parent1/Separator1/Child1)[1]', 'varchar(max)') as Col1,
x.value('(Parent2/Separator2/Child2)[1]', 'varchar(max)') as Col2,
x.value('(Parent3)[1]', 'varchar(max)') as Col3
from [XMLTable] T
cross apply T.XMLCOL.nodes('/Root/Elem1') a(x)
上記のクエリには約1秒かかります。なかでも最速のようです。したがって、paramsを使用してテーブル値関数を使用する代わりに、上記のクエリをADO.NET機能を使用して動的に準備し、オンザフライで実行できます。
訂正してください...?