2012-09-10 32 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