优化 XML 个无子元素的删除
Optimize deletion of XML elements without children
我有一个很大的 XML
值存储在变量中。我首先删除属性 @Suspended
设置为 1
:
的所有 condition
元素
SET @A.modify('delete /definitions/definition/conditions/group/condition[@Suspended=1]')
然后我想删除所有 group
没有留下任何 condition
元素的元素(上次删除后没有留下子元素)。我已经设法使用以下语句做到这一点:
SET @A.modify('delete for $Node in /definitions/definition/conditions/group
where not ( ($Node/condition)[1] instance of element() )
return $Node
')
第一次删除非常快 - 0
秒。第二次删除执行时间约为8
秒
如果可能的话,我正在寻找better/faster执行第二次删除的方法。
以下是示例 XML
结构:
<definitions>
<definition>
<conditions>
<group name="Group 1">
<condition name="condition" type="answerisin" objType="question" objID="213219" Suspended="1">
<value name="parameter">12</value>
</condition>
<condition name="condition" type="answerisin" objType="question" objID="113219" Suspended="1">
<value name="parameter">4</value>
</condition>
</group>
</conditions>
</definition>
<definition>
<conditions>
<group name="Group 1">
<condition name="condition" type="answerisin" objType="question" objID="213219" Suspended="1">
<value name="parameter">34</value>
</condition>
</group>
<group name="Group 2">
<condition name="condition" type="answerisin" objType="question" objID="213219">
<value name="parameter">12</value>
</condition>
</group>
</conditions>
</definition>
</definitions>
您可以重写为:
set @A.modify('delete /definitions/definition/conditions/group[empty(condition)]');
但我怀疑它会更快。查询计划略有不同,但在影响性能的部分大同小异。
另一个可能对您有用的选项是将 XML 分解为 definitions/definition
上的 table 变量,修改 table 中的 XML变量,然后使用 for xml path
.
重新创建 XML
declare @T table(X xml);
insert into @T(X)
select T.X.query('.')
from @A.nodes('/definitions/definition') as T(X);
update @T
set X.modify('delete /definition/conditions/group[empty(condition)]');
set @A = (
select T.X as '*'
from @T as T
for xml path(''), root('definitions')
);
在我的测试中,粉碎 XML 并进行小块修改比修改大块 XML 快 10 倍。但这当然取决于您实际 XML 的样子,以及 definitions/definition
上的粉碎是否足够细。
我有一个很大的 XML
值存储在变量中。我首先删除属性 @Suspended
设置为 1
:
condition
元素
SET @A.modify('delete /definitions/definition/conditions/group/condition[@Suspended=1]')
然后我想删除所有 group
没有留下任何 condition
元素的元素(上次删除后没有留下子元素)。我已经设法使用以下语句做到这一点:
SET @A.modify('delete for $Node in /definitions/definition/conditions/group
where not ( ($Node/condition)[1] instance of element() )
return $Node
')
第一次删除非常快 - 0
秒。第二次删除执行时间约为8
秒
如果可能的话,我正在寻找better/faster执行第二次删除的方法。
以下是示例 XML
结构:
<definitions>
<definition>
<conditions>
<group name="Group 1">
<condition name="condition" type="answerisin" objType="question" objID="213219" Suspended="1">
<value name="parameter">12</value>
</condition>
<condition name="condition" type="answerisin" objType="question" objID="113219" Suspended="1">
<value name="parameter">4</value>
</condition>
</group>
</conditions>
</definition>
<definition>
<conditions>
<group name="Group 1">
<condition name="condition" type="answerisin" objType="question" objID="213219" Suspended="1">
<value name="parameter">34</value>
</condition>
</group>
<group name="Group 2">
<condition name="condition" type="answerisin" objType="question" objID="213219">
<value name="parameter">12</value>
</condition>
</group>
</conditions>
</definition>
</definitions>
您可以重写为:
set @A.modify('delete /definitions/definition/conditions/group[empty(condition)]');
但我怀疑它会更快。查询计划略有不同,但在影响性能的部分大同小异。
另一个可能对您有用的选项是将 XML 分解为 definitions/definition
上的 table 变量,修改 table 中的 XML变量,然后使用 for xml path
.
declare @T table(X xml);
insert into @T(X)
select T.X.query('.')
from @A.nodes('/definitions/definition') as T(X);
update @T
set X.modify('delete /definition/conditions/group[empty(condition)]');
set @A = (
select T.X as '*'
from @T as T
for xml path(''), root('definitions')
);
在我的测试中,粉碎 XML 并进行小块修改比修改大块 XML 快 10 倍。但这当然取决于您实际 XML 的样子,以及 definitions/definition
上的粉碎是否足够细。