我正在尝试优化依赖于少量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)') + '%')
...
即使更改似乎降低了执行计划中的成本,但优化后存储过程运行得更慢。这给我留下了几个问题:
答案 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)