加速SQL Server 2005中的XML查询

时间:2010-09-13 15:00:08

标签: sql xml performance

我将所有数据存储在SQL Server 2005的XML列中。

随着越来越多的记录被插入,我注意到查询速度正在减慢。我尝试过创建一个主XML索引,以及一个辅助VALUE索引,但这并没有帮助提高速度。

我缺少哪些提示,想法或技巧?

我查询的示例视图:

SELECT Id
, CaseNumber
, XmlTest.value('(/CodeFiveReport/ReportEvent/StartDate)[1]', 'varchar(25)') + ' ' + XmlTest.value('(/CodeFiveReport/ReportEvent/StartTime)[1]', 'varchar(25)') as StartDate
, XmlTest.value('(/CodeFiveReport/@Status)[1]', 'varchar(10)') as [Status]
, XmlTest.value('(/CodeFiveReport/ReportEvent/Address/PatrolDistrict/@Name)[1]', 'varchar(100)') as PatrolDistrict
, XmlTest.value('(/CodeFiveReport/PrimaryUnit/@Name)[1]', 'varchar(40)') as PrimaryUnit
, XmlTest.value('(/CodeFiveReport/ReportEvent/Address/@StreetNumber)[1]', 'varchar(50)') + ' ' + XmlTest.value('(/CodeFiveReport/ReportEvent/Address/@StreetName)[1]', 'varchar(50)') + ' ' + XmlTest.value('(/CodeFiveReport/ReportEvent/Address/StreetSuffix/@Name)[1]', 'varchar(50)') + ' ' + XmlTest.value('(/CodeFiveReport/ReportEvent/Address/@City)[1]', 'varchar(50)') + ' ' + XmlTest.value('(/CodeFiveReport/ReportEvent/Address/State/@Abbreviation)[1]', 'varchar(50)') + ' '  + XmlTest.value('(/CodeFiveReport/ReportEvent/Address/@ZipCode)[1]', 'varchar(50)') as Location
, XmlTest.value('(/CodeFiveReport/ReportEvent/ReportType/@Name)[1]', 'varchar(50)') as ReportType
, XmlTest.value('(/CodeFiveReport/ReportEvent/Offenses/OffenseDescription/OffenseType/@CodeAndDescription)[1]', 'varchar(50)') as IncidentType
, XmlTest as Report
, CreatedBy as UserId
, XmlTest.value('(/CodeFiveReport/PrimaryUnit/@ID)[1]', 'integer') as UnitId
, XmlTest.value('(/CodeFiveReport/PrimaryUnit/@Code)[1]', 'varchar(6)') as UnitCode
, XmlTest.value('(/CodeFiveReport/Owner/AgencyID)[1]', 'char(2)') as AgencyId   
, IsLocked
, LockedBy
, XmlTest.value('(/CodeFiveReport/VersionUsed)[1]', 'varchar(20)') as VersionUsed
FROM UploadReport
WHERE XmlTest.value('(/CodeFiveReport/Owner/AgencyID)[1]', 'char(2)') = '06'

4 个答案:

答案 0 :(得分:4)

阅读XML Best Practices for Microsoft SQL Server 2005

我记得最重要的两个提示是

  • 使用node/text()代替node代替xpath。
  • 尝试永远不要在xpath表达式中使用../,因为它会减慢它的速度非常重要

答案 1 :(得分:4)

仅当结果用于插入表或连接时,查询才会遇到性能问题。简单地从管理工作室中选择返回值几乎是即时的。使用INSERT INTO的前缀,同样的工作需要30秒以上。

添加/text()之后,例如

from @list.nodes('/List/Id/text()') as C(C)

而不是我所拥有的:

from @list.nodes('/List/Id') as C(C)

即使使用插入,这也会使查询恢复为零秒。

答案 2 :(得分:1)

好吧,我能够使用两个子查询大大加快查询速度,然后从该结果集中解析XML。

答案 3 :(得分:1)

通过使用以下提示,我能够在4分30秒到20秒的时间内加快查询速度:

http://blogs.technet.com/b/wardpond/archive/2005/06/23/sql-server-2005-xquery-performance-tips.aspx

我有这个:

SELECT
Package.query('(/D/D[@n="Main"]/node()[@n="FirstNames"]/text())[1]') as [Main.FirstNames],
Package.query('(/D/D[@n="Main"]/node()[@n="LastName"]/text())[1]') as [Main.LastName],

......更多列

改变这一点完全不同:

SELECT
Package.query('(/D[1]/D[@n="Main"][1]/node()[@n="FirstNames"][1]/text())[1]') as [Main.FirstNames],
Package.query('(/D[1]/D[@n="Main"][1]/node()[@n="LastName"][1]/text())[1]') as [Main.LastName],

......更多列

通过上面的查询,这也可能对您有所帮助。