2012-05-24 70 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)