【问题标题】:Optimize deletion of XML elements without children优化删除没有子元素的 XML 元素
【发布时间】:2015-05-14 14:09:58
【问题描述】:

我有一个很大的XML 值存储在变量中。我首先删除属性@Suspended 设置为1 的所有condition 元素:

 SET @A.modify('delete /definitions/definition/conditions/group/condition[@Suspended=1]')

然后我想删除所有没有留下任何condition 元素的group 元素(上次删除后没有留下任何子元素)。我已经设法使用以下语句来做到这一点:

SET @A.modify('delete for $Node in /definitions/definition/conditions/group 
                                where not ( ($Node/condition)[1] instance of element() )
                                return $Node
                             ')

第一次删除非常快 - 0 秒。第二次删除执行时间约为8秒。

如果可能,我正在寻找一种更好/更快的方法来执行第二次删除。


以下是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>

【问题讨论】:

  • 我不确定您为什么要使用这个相当复杂的语句。 delete /definitions/definition/conditions/group[empty(condition)] 呢?不过,我不确定它是否更快:取决于 SQL Server 是否严重优化了您的查询或更改实际数据需要很多时间。
  • 我想最好用reference to some reference 回答这个问题。在这种情况下,它会检查子轴步骤condition 的结果序列是否为空,即测试是否缺少condition 子级。从某种意义上说,这是一种否定[condition]。

标签: xml tsql xpath sql-server-2012 xquery


【解决方案1】:

你可以改写成这样:

set @A.modify('delete /definitions/definition/conditions/group[empty(condition)]');

但我怀疑它会更快。查询计划有些不同,但在影响性能的部分大体相同。

另一个可能对您有用的选项是将 XML 分解为 definitions/definition 上的表变量,修改表变量中的 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 上的粉碎是否足够细。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-18
    • 1970-01-01
    • 2020-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多