2

XML変数入力のいくつかの型パラメーターに依存するストアドプロシージャを最適化しようとしています。実行プランの分析は、これらのパラメーターのデータへのアクセスに関連する高コストを示しています。

与えられた:

DECLARE @FirstNameXML  XML;

の形式で

<FirstNames>
  <Name>John</Name>
  <Name>Joe</Name>
</FirstNames>

実行する必要のある操作がいくつかあります(パラメーターがnull以外であると想定)。

提供された名前の数

SET @FirstNameCount = 
  (SELECT COUNT(FirstNameValues.Name.value('.','VARCHAR(50)'))
  FROM @FirstNameXML.nodes('/FirstNames/Name') 
  AS FirstNameValues(Name))

count=1の場合

...
AND First_Name LIKE
  (SELECT TOP(1) FirstNameValues.Name.value('.','VARCHAR(50)') + '%'
  FROM @FirstNameXML.nodes('/FirstNames/Name') 
  AS FirstNameValues(Name))
...

それ以外の場合、カウント>1の場合

...
AND First_Name IN
(SELECT FirstNameValues.Name.value('.','VARCHAR(50)')
  FROM @FirstNameXML.nodes('/FirstNames/Name') 
  AS FirstNameValues(Name))
...

私はいくつかの最適化を試みました:

カウントクエリを次のように変更します

SET @FirstNameCount = 
  (SELECT CAST(CAST(@FirstNameXML.query('count(/FirstNames/Name)') 
    AS VARCHAR(10)) AS INT)

count == 1クエリを次のように変更します

...
AND First_Name LIKE
  (SELECT @FirstNameXML.value('(/FirstNames/Name)[1]', 'VARCHAR(50)') + '%')
...

変更によって実行プランのコストが削減されたように見えても、最適化後のストアドプロシージャの実行速度はどういうわけかさらに遅くなります。これは私にいくつかの質問を残します:

  1. 実装した最適化を誤解していますか?
  2. 全体としてこれを実行するためのより効率的な方法はありますか?(XMLパラメーターベースのクエリ)
4

1 に答える 1

1

XML からの行をテーブル変数または一時テーブルに追加します。テーブル変数/一時テーブルの名前列にインデックスがあることを確認してください。また、count が 1 または多数の場合に異なるクエリを用意する必要もないと思います。この方法では、XML を一度だけ解析します。

ノート。XML に関して言えば、実行計画のコストは信頼できません。set statistics time on代わりに、実際のパフォーマンスをテストして測定することをお勧めします。

-- Test data
declare @FirstNameXML xml;
set @FirstNameXML = 
'<FirstNames>
  <Name>John</Name>
  <Name>Joe</Name>
</FirstNames>'

-- Put your data in a table variable.
-- Have Name as a primary key and you will get an index
declare @T table
(
  Name varchar(50) primary key
)

-- Add rows from XML to @T
insert into @T(Name)
select distinct T.N.value('.', 'varchar(50)')
from @FirstNameXML.nodes('FirstNames/Name') as T(N)

select *
from YourTable
where First_Name in (select Name from @T)
于 2012-05-25T05:43:53.750 に答える