2010-09-13 144 views
1

我将所有数据都存储在SQL Server 2005的XML列中。加快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' 

回答

1

嗯,我能使用两个子查询,然后解析从结果集的XML大大加快我的查询。

+0

你可以加速多一点,看我的回复 – CaffGeek 2010-09-16 17:02:35

4

阅读XML Best Practices for Microsoft SQL Server 2005

两个提示我记得最让在speead差异是

  • 使用node/text(),而不是只是node您的XPath。
  • 尝试从来没有使用XPath表达式../,因为它减缓下来显著
+0

非常感谢,但我不认为这些提示有助于上述查询!是通过价值返回一个单身最有效的方式来查询? – mint 2010-09-16 18:03:46

+0

@mint,例如'(/ CodeFiveReport/ReportEvent/StartDate)[1]'你可以将'/ text()'添加到xpath中,并且它应该略微提高性能。我已经看到15分钟的查询缩短为秒,因为像x /添加'/ text()'和/或删除任何出现的'../'。不过,您不会将它用于@属性,因为它们已经是文本。只是用'/ CodeFiveReport/ReportEvent/StartDate',sql服务器不知道它是否返回节点,它必须转换为文本或文本。使用'/ text()'它不需要检查。 – CaffGeek 2010-09-16 18:51:34

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], 

...很多更多的列

通过你上面的查询的外观,这可能帮助你,以及。

4

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

加入/text()

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

什么,而不是我有后:

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

这使该查询返回到零秒的执行,即使插入。