优化 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 上的粉碎是否足够细。