我正在使用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
会更快吗?
答案 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()
函数的性能。