2012-05-24 72 views
2

我想优化一个存储过程,它依赖于几个XML类型的变量输入参数。对执行计划的分析显示,与访问这些参数中的数据相关的成本较高。在存储过程中高效地访问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) 

改变计数== 1查询

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

不知存储过程运行,即使变化似乎已经减少了执行计划成本的优化后,更慢。这给我留下了几个问题:

  1. 我误解了我实现的优化?
  2. 整体上有没有更有效的方法呢?(基于XML参数的查询)
+1

使用xml来填充一个临时表,然后加入到它,本来是我去的方式。 –

+0

@marc_s你编辑的内​​容到底是什么?你删除了所有我加入重点的尝试(关于标题中的关键字和我所问的实际问题)。 –

+0

过分强调并不是一件好事..我不认为这里的标题应该全部用首字母大写 - 但那只是我...... –

回答

1

将XML中的行添加到表变量或临时表中。确保表变量/ temp表中名称列上有索引。当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)