2011-05-26 32 views
6

我正在用SQL Server 2008的xml數據類型做一些粗略的基準測試。我見過很多地方在where子句中使用.exist。我最近比較了兩個查詢,並得到了奇怪的結果。where子句中哪個更快,存在或.value?

select count(testxmlrid) from testxml 
where Attributes.exist('(form/fields/field)[@id="1"]')=1 

這個查詢需要大約1.5秒跑,沒有索引上的任何東西,但主鍵(testxmlrid)

select count(testxmlrid) from testxml 
where Attributes.value('(/form/fields/field/@id)[1]','integer')=1 

在otherhand這個查詢大約需要0.75秒運行。

我正在使用無類型的XML,並且我的基準測試正在發生在SQL Server 2008 Express實例上。數據集中大約有15,000行,每個XML字符串大約25行。

這些結果是否正確?如果是這樣,爲什麼大家都用.exist?我做錯了什麼,.exist可能會更快?

回答

3

你不計數相同的東西。您的.exist查詢(form/fields/field)[@id="1"]將檢查XML中出現的所有@id,直到它找到一個值爲1,並且您的.value查詢(/form/fields/field/@id)[1]僅獲取第一個出現的@id

測試此:

declare @T table 
(
    testxmlrid int identity primary key, 
    Attributes xml 
) 

insert into @T values 
('<form> 
    <fields> 
     <field id="2"/> 
     <field id="1"/> 
    </fields> 
    </form>') 

select count(testxmlrid) from @T 
where Attributes.exist('(form/fields/field)[@id="1"]')=1 

select count(testxmlrid) from @T 
where Attributes.value('(/form/fields/field/@id)[1]','integer')=1 

.exist查詢計數是1,因爲它找到@id=1在第二field節點和.value查詢計數是0,因爲它只會檢查的@id第一次出現的值。

An .exist查詢只檢查@id的第一個匹配項的值,就像您的.value查詢看起來一樣。

select count(testxmlrid) from @T 
where Attributes.exist('(/form/fields/field/@id)[1][.="1"]')=1 
+1

是否存在'()'不短路,一旦它找到第一次出現的呢? – Yuck 2011-05-27 12:10:12

+0

@Yuck - 是的,但在這種情況下,'.exist'查詢正在搜索「@ id = 1」的存在。如果第一次出現如果「@ id」不是1時,它會繼續搜索。 '.value'查詢首次出現「@ id」的值,如果該值不是1,則不會繼續搜索。 – 2011-05-27 13:30:50