XMLドキュメントからいくつかのノードを処理するクエリを実行しています。私の推定サブツリーのコストは数百万単位であり、それはすべて、XPathを介してxml列から抽出したいくつかのデータに対してSQLサーバーが実行しているソート操作に由来するようです。Sortオペレーションの推定行数は約1900万ですが、実際の行数は約800です。クエリ自体は適切に実行されますが(1〜2秒)、クエリのパフォーマンスとその理由について疑問に思っています。違いはとても大きいですか?
XMLドキュメントからいくつかのノードを処理するクエリを実行しています。私の推定サブツリーのコストは数百万単位であり、それはすべて、XPathを介してxml列から抽出したいくつかのデータに対してSQLサーバーが実行しているソート操作に由来するようです。Sortオペレーションの推定行数は約1900万ですが、実際の行数は約800です。クエリ自体は適切に実行されますが(1〜2秒)、クエリのパフォーマンスとその理由について疑問に思っています。違いはとても大きいですか?
回答:
XML列で生成された統計はありません。推定値は、XMLのクエリ時に使用される式に基づいて推測されます。
このテーブルを使用して:
create table T(XMLCol xml not null)
insert into T values('<root><item value = "1" /></root>')
そして、このかなり単純なXMLクエリ:
select X.N.value('@value', 'int')
from T
cross apply T.XMLCol.nodes('root/item') as X(N)
返される1行が返されますが、返される推定行数は200です。その1行のXML列にどのXMLを挿入するか、またはXML列にどれだけ挿入するかに関係なく、200になります。
これは、推定行数が表示されたクエリプランです。
見積もりを改善する、または少なくとも変更する方法は、クエリオプティマイザーにXMLに関する情報を提供することです。この場合、それが本当にXMLのルートノードであることを知っているので、このroot
ようにクエリを書き換えることができます。
select X2.N.value('@value', 'int')
from T
cross apply T.XMLCol.nodes('root[1]') as X1(N)
cross apply X1.N.nodes('item') X2(N)
これにより、返される5行の見積もりが得られます。
クエリを書き直しても、XMLの細断処理が速くならない可能性がありますが、見積もりが優れている場合、クエリオプティマイザーが残りのクエリに対してより賢明な決定を下せる可能性があります。
Michael Rysによるプレゼンテーション以外に、推定値のルールについてのドキュメントは見つかりませんでした。
基本カーディナリティの推定値は常に10'000行です。
プッシュされたパスフィルターに基づくいくつかの調整