2012-09-10 86 views
0

我有一個歷史表,它具有主表的事務記錄信息,在此表中我使用了XML列來存儲該事務信息。包含數據的表結構看起來像。使用Xquery從XMLAttribute獲取數據時的性能問題

Table information

在內容的XML數據被存儲爲象下面的XML。

 <Answers> 
     <AnswerSet> 
     <Answer questionId="ProductCode">S3404</Answer> 
     <Answer questionId="ProductName">Parabolic Triple</Answer> 
     <Answer questionId="LegacyOptionID" selectedvalue="1389">1389</Answer> 
     <Answer questionId="LegacyContentID" selectedvalue="624">624</Answer> 
     <Answer questionId="LegacyPageID" selectedvalue="355">355</Answer> 
     <Answer questionId="LegacyParentID" selectedvalue="760">760</Answer> 
    </AnswerSet> 
    </Answers> 

在所有行結構是相同的,但數據是在回答節點不同,我想其中有產品代碼=「S3404」和CreatedDate是新的數據。像

select n2.* from nodehistory n2 CROSS APPLY n2.content.nodes('Answers/AnswerSet') T(c) WHERE c.value('./Answer[@questionId="ProductCode"][1]','varchar(100)') ='J154' 

產品代碼

我已創建的查詢必須爲每一個NODEID獨特的數據,但這是同樣的NODEID返回多行,因爲這是交易表,以便同XML可以存儲多個時間,爲這需要像Created by desc命令那樣的條件,但由於我認爲XML處理,執行此查詢需要更多的時間。

我們可以這樣做嗎?首先通過CreatedDate desc從NodeHistory順序獲取Select Top 1 nodeid,然後搜索XML部分。

請建議你獲得更好的性能

回答

0

合適的意見。如果你不這樣做與XML數據的其他東西,然後.exist應該比.value的更有效率。我認爲BOL在這方面有一個說明。您還可以使用SQL:變量來使這個更通用的,比如像:

declare @produceCode varchar(20) = 'S3404' 

select n2.* 
from nodehistory n2 
    inner join (select max(id) id from #nodehistory group by nodeId) maxId ON n2.id = maxId.id 
where n2.content.exist('Answers/AnswerSet/Answer[@questionId="ProductCode"][.=sql:variable("@produceCode")]') = 1 

我用一個子查詢來限制結果集以每NODEID最大(ID)。您的要求可能稍有不同,但您明白了。

在性能方面,XML索引可以轉換SQL/XML查詢,但需要付出代價。對於存儲,您將需要原始表格大小的2-5倍,因此您必須對數據進行權衡。如果你決定去與XML索引,那麼性能指標應有助於這種類型的查詢,如

-- create the primary XML index 
CREATE PRIMARY XML INDEX xmlidx_nodehistory ON nodehistory(content) 
GO 

CREATE XML INDEX xmlprpidx_nodehistory ON nodehistory(content) 
USING XML INDEX xmlidx_nodehistory FOR PROPERTY 
go 

declare @produceCode varchar(20) = 'S3404' 

select n2.* 
from nodehistory n2 
    inner join (select max(id) id from nodehistory group by nodeId) maxId ON n2.id = maxId.id 
where n2.content.exist('Answers/AnswerSet/Answer[@questionId="ProductCode"][.=sql:variable("@produceCode")]') = 1 

中查看SQL XML性能調整思路這些偉大的文章:對於XML

性能優化在SQL Server上的SQL Server數據類型2005

http://msdn.microsoft.com/en-us/library/ms345118.aspx

XML索引2005

http://msdn.microsoft.com/en-us/library/ms345121(SQL.90).aspx