2015-09-18 229 views
0

在SQL Server 2012中,我有一個包含1列的表,其中包含一個XML列 - XMLdata。 XML的大小約爲10 MB。我寫了一個查詢,但執行需要大約1個小時。有沒有什麼選擇如何重寫查詢,它會更快地工作?SQL Server:使用XQuery優化TSQL查詢

XML的結構:

<Settings> 
    <Group Name="A"> 
     <Group Name="AA"> 
      <Group Name="AAA"> 
       <Parameter Name="aaa"> 
        <Value>test1</Value> 
        <Items> 
          <Item Index="0" Name="A"/> 
          <Item Index="1" Name="B"/> 
        </Items> 
       </Parameter> 
      </Group> 
     </Group> 
    </Group> 
</Settings> 

查詢:

SELECT 
    A.B.value('../../../../../@Name', 'nvarchar(100)') + '/' + A.B.value('../../../../@Name', 'nvarchar(100)') + '/' + A.B.value('../../../@Name', 'nvarchar(100)') AS BlockPath 
    , A.B.value('../../@Name', 'nvarchar(100)') AS ParameterName 
    , A.B.value('./@Index', 'nvarchar(100)') AS ItemIndex 
    , A.B.value('./@Name', 'nvarchar(100)') AS ItemName 
FROM 
    [table] 
CROSS APPLY 
    XMLdata.nodes('//Item') AS A(B); 
+2

你試過看xml索引嗎? https://msdn.microsoft.com/zh-cn/library/bb934097.aspx –

+0

謝謝您的建議。我迅速提高了表現。 –

回答

3

儘量多用集中的XPath,而不是出了名的低效//Items方法。

我嘗試這樣做,得到相同的結果,以及更好的性能:

SELECT 
    BlockPath = XC.value('../../../@Name', 'nvarchar(100)') + '/' + XC.value('../../@Name', 'nvarchar(100)') + '/' + XC.value('../@Name', 'nvarchar(100)'), 
    ParameterName = XC.value('@Name', 'varchar(100)'), 
    ItemIndex = XCItem.value('@Index', 'int'), 
    ItemName = XCItem.value('@Name', 'varchar(100)') 
FROM 
    [table] 
CROSS APPLY 
    XMLdata.nodes('/Settings/Group/Group/Group/Parameter') AS XT(XC) 
CROSS APPLY 
    XC.nodes('Items/Item') AS XT2(XCItem); 

第一CROSS APPLY得到<Parameter>節點 - 但與任何//裏面有直接的XPath - 然後第二CROSS APPLY得到每個<Parameter>節點下的Items/Item節點。

試試這個 - 你有多少改進?

+0

我用我的代碼和你的代碼'SELECT TOP 100'。我的代碼耗時78秒,你的代碼耗時47秒。這更好,但仍然放緩。 –

+0

我添加了主要和輔助XML索引,並且我迅速提高了性能。 'SELECT TOP 100'需要3秒鐘才能執行。 –

+0

@AljPra:好的,很高興聽到。我對XML索引的使用經驗不足 - 他們加快了XQuery的速度,但他們也使我的數據庫從大約1.5 GB擴展到大約11 GB ...... –

1

正如評論中所建議的那樣,在您的專欄上創建XML Index是個好主意。你也可以查詢你的XML字段爲marc_s建議。這兩者的結合應該會給你帶來巨大的性能提升。