在where子句中哪个更快.exist或.value?

时间:2011-05-26 22:58:57

标签: sql-server performance xpath xquery-sql

我正在使用SQL Server 2008的xml数据类型进行一些粗略的基准测试。我在.exist子句中看到了很多使用where的地方。我最近比较了两个查询,结果很奇怪。

select count(testxmlrid) from testxml
where Attributes.exist('(form/fields/field)[@id="1"]')=1

此查询运行大约需要1.5秒,除了主键(testxmlrid)之外没有任何索引

select count(testxmlrid) from testxml
where Attributes.value('(/form/fields/field/@id)[1]','integer')=1

另一方面,此查询需要大约0.75秒才能运行。

我正在使用非类型化的XML,我的基准测试是在SQL Server 2008 Express实例上进行的。数据集中大约有15,000行,每个XML字符串长约25行。

这些结果我是否正确?如果是这样,为什么每个人都使用.exist?我做错了什么,.exist会更快吗?

2 个答案:

答案 0 :(得分:3)

你不是在计算同样的事情。您的.exist查询(form/fields/field)[@id="1"]会检查XML中@id的所有匹配项,直到找到值为1的{​​{1}}和.value查询(/form/fields/field/@id)[1]为止获取第一次出现的@id

测试一下:

declare @T table
(
  testxmlrid int identity primary key,
  Attributes xml
)

insert into @T values
('<form>
    <fields>
      <field id="2"/>
      <field id="1"/>
    </fields>
  </form>')

select count(testxmlrid) from @T
where Attributes.exist('(form/fields/field)[@id="1"]')=1

select count(testxmlrid) from @T
where Attributes.value('(/form/fields/field/@id)[1]','integer')=1

.exist查询计数为1,因为它在第二个@id=1节点中找到field.value查询计数为0,因为它只检查该值的值第一次出现@id

.exist查询仅检查第一次出现@id的值,例如.value查询。

select count(testxmlrid) from @T
where Attributes.exist('(/form/fields/field/@id)[1][.="1"]')=1

答案 1 :(得分:0)

差异可以来自您的索引。

PATH索引将提升exist()子句上WHERE谓词的性能,而PROPERTY索引将提升value()函数的性能。

读: http://msdn.microsoft.com/en-us/library/bb522562.aspx