2010-09-13 153 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) 

這使該查詢返回到零秒的執行,即使插入。