【问题标题】:Stored procedure XML parsing performance存储过程 XML 解析性能
【发布时间】:2013-07-07 03:56:48
【问题描述】:

我有一个带有 XML 变量解析代码部分的 SP。

XML 得到了下一个结构:

<root>
  <ID Reason="1">1</ID>
  <ID Reason="2">2</ID>
  <ID Reason="2">3</ID>
  <ID Reason="1">5</ID>
</root>

SP 代码部分:

INSERT INTO #tmp_table (ID,Reason)
SELECT IDs.ID.value('.', 'int')
     , IDs.ID.value('@Reason', 'int')
FROM @I_XML.nodes('/root/ID') AS Ids(ID)

当我尝试使用具有 100000 行的 XML 输入参数运行 SP 时,它会花费大量时间并且执行成本为 5%。

如何改进 SP 代码部分以使其更快?

【问题讨论】:

  • 如果 XML 看起来像这样,调用者是否有理由不能改为传递表值参数?
  • 不,我不能改变输入参数的类型
  • 我不会担心执行成本,但“疯狂的时间”听起来有点严重。那实际上是多少时间?在我在笔记本电脑上进行的测试中,您的查询需要 2 秒,而在我的答案中重写需要 1.5 秒。 OPENXML 版本耗时 4 秒。
  • 您使用的是 Sql Server 2005 吗?有一个“基于元素的 xml 粉碎”错误,仅供参考。
  • 如其他地方所述,我更喜欢创建一个@variable 或#temp 表...将 xml 切碎到其中.........然后点击“真实”表。将 2 个动作分开,切碎,然后是 CUD'ing。

标签: sql-server xml performance tsql parsing


【解决方案1】:

您可以尝试更改获取节点值的方式。

INSERT INTO #tmp_table (ID,Reason)
SELECT IDs.ID.value('text()[1]', 'int')
     , IDs.ID.value('@Reason', 'int')
FROM @I_XML.nodes('/root/ID') AS Ids(ID)

通过指定text() 节点,您将获得稍微不同的执行计划,而不会改变结果。仅使用节点名称(在您的情况下为 .)将使 SQL Server 对指定节点下的所有节点值进行深度搜索。在您的 XML 中没有,因此结果将是相同的。

【讨论】:

  • 我需要为 @Reason 添加 text() 吗?没有?
  • @Aleksandr 不,属性只是单个值,不能是其他节点的父节点。
【解决方案2】:

尝试使用OPENXML:

declare @hXml int

exec sp_xml_preparedocument @hXml output, @YourXmlParam

insert into #tmp_table
select ID, Reason
from OPENXML(@hXml, '/root/ID') with (ID int '.', Reason int '@Reason')

exec sp_xml_removedocument @hXml

【讨论】:

  • 这是 2005 年被替换的 Sql Server 2000 语法。
  • 它没有被替换,仍然是实际的 (even in 2012)。在某些情况下它比使用nodes()value() 更快,但在这种情况下我不确定。
  • 好吧,我猜“替换”这个词不正确。 “更新”和“保持向后兼容性”。但你是对的,你可能会经常发现仅基于 xml 结构和大小的情况下它的性能更好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-25
  • 1970-01-01
  • 1970-01-01
  • 2017-04-20
  • 2011-06-22
相关资源
最近更新 更多