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

Ear*_*rlz 6 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
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

Mik*_*son 3

你们计算的不是同样的事情。您的.exist查询会检查XML 中(form/fields/field)[@id="1"]所有出现的,直到找到具有该值的一个,并且您的查询仅获取第一个出现的。@id1.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
Run Code Online (Sandbox Code Playgroud)

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

.exist仅检查第一次出现的值的查询类似于您的查询@id.value

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