我将所有数据存储在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'
答案 0 :(得分:4)
阅读XML Best Practices for Microsoft SQL Server 2005
我记得最重要的两个提示是
node/text()
代替node
代替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],
......更多列
通过上面的查询,这也可能对您有所帮助。