提高SQL Server中的Xquery性能

时间:2016-02-23 11:12:38

标签: sql sql-server xml azure xquery

我有一个Azure SQL数据库,包含1个表和大量记录(超过75 000个)。该表包含XML数据类型的列。此列如下所示:

<error application="application" host="host" type="exception" message="message" ...>
  <serverVariables>
    <item name="name1">
      <value string="text" />
    </item>
    <item name="name2">
      <value string="text2" />
    </item>
    <item name="name3">
      <value string="text3" />
    </item>
    <item name="name4">
      <value string="text4" />
    </item>
    <item name="name5">
      <value string="text5" />
    </item>
    <item name="name6">
      <value string="text6" />
    </item>
    <item name="name7">
      <value string="text7" />
    </item>
  </serverVariables>
</error>

如果我想获取项属性名称为name5且值属性字符串为text5的所有记录,我会写一个这样的查询:

SELECT *
FROM Table
WHERE XmlColumn.exist('//item[@name[. = "name5"] and value/@string[. = "text5"]]') = 1

这使用XQuery并且必须查询整个文档。这也很慢。

我的问题是如何才能使此查询执行得更快?是否可以在该列上声明XML索引?还有其他可能使XQueries执行得更快吗?

1 个答案:

答案 0 :(得分:2)

我刚做了一点测试。使用.nodes(),您可以得到3%左右......实际上并非如此。在我的测试机器(只是一台简单的笔记本电脑)中,我在~5秒内得到了100.000行的结果。事实并非那么糟糕......如果你想要快速,你必须从XML中获取搜索值或使用XML索引:

测试场景

首先,我创建一个测试表并用100.000行填充它。随机数(0到1000)应该导致每个随机数约100行。此数字作为XML的值放入varchar col

然后我打电话就像你需要它.exist().nodes()一样,第二个小优势,但都需要5到6秒。 事实上,我做了两次调用:第二次以交换顺序和略微改变的搜索参数和“// item”而不是完整路径,以避免通过缓存结果或计划出现误报。

然后我创建一个XML索引并执行相同的调用

现在 - 真的让我感到惊讶! - {{1>} 完整路径 比之前(9秒)慢,但.nodes下降到半秒,完整路径甚至低至约0.10秒

所以我建议:使用索引并使用.exist()

进行操作

这是copy'n'paste和自我测试的代码

.exist()