2015-09-18 153 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建议。这两者的结合应该会给你带来巨大的性能提升。