在存储过程中有效地访问Xml参数

时间:2012-05-24 21:57:27

标签: xml sql-server-2005 stored-procedures

我正在尝试优化依赖于少量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))
...

如果计数&gt; 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)

将计数== 1查询更改为

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

即使更改似乎降低了执行计划中的成本,但优化后存储过程运行得更慢。这给我留下了几个问题:

  1. 我误解了我实施的优化措施吗?
  2. 是否有更有效的方法来解决这个问题?(基于XML参数的查询)

1 个答案:

答案 0 :(得分:1)

将XML中的行添加到表变量或临时表中。确保表变量/ temp表中的Name列有一个索引。我也没有看到当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)