AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 320285
Accepted
lifeisajourney
lifeisajourney
Asked: 2022-11-29 09:14:52 +0800 CST2022-11-29 09:14:52 +0800 CST 2022-11-29 09:14:52 +0800 CST

SQL Server 中的 XML 与 UDF 性能

  • 772

我有一种情况,我必须决定是接收 XML 作为存储过程的输入参数,还是接收逗号分隔值列表,并使用多表值函数解析它们。

从逻辑上讲,我更喜欢 XML 而不是 udfs,因为 udfs 会导致很多性能问题。但我看到后端的 XML 也使用表值函数来解析 xml。我想知道 XML 是否真的比多表 UDF 好,如果是,是什么让它更好?

CREATE FUNCTION [dbo].[tmp_array_commaValues] ( @string varchar(4000))
RETURNS  @final TABLE(Value varchar(100))
AS
begin

    WITH tmp_cte(start, stop) AS

    (
      SELECT  1, CHARINDEX(',' , @string )
      
      UNION ALL
      
      SELECT  stop + 1, CHARINDEX(',' ,@string  , stop + 1)
      FROM tmp_cte
      WHERE stop > 0
    )

    insert into @final
    SELECT   SUBSTRING(@string , start, CASE WHEN stop > 0 THEN stop-start ELSE 4000 END) AS stringValue
    FROM tmp_cte   

    return
end   

/* query */
Select value 
  From [dbo].[tmp_array_commaValues]('TAG,ABC,ZYX,BAG,TRY,LAG,LEAD,NETHERLANDS,TAG1,ABC1,ZYX1,BAG1,TRY1,SUN12,NANGE1')

/********** XML *********/
Declare @xml XML = '<root><id>Tag</id><id>Lag</id>
<id>Tag1</id><id>Lag1</id>
<id>Tag2</id><id>Lag2</id>
<id>Tag3</id><id>Lag3</id>
<id>Tag4</id><id>Lag4</id>
<id>Tag5</id><id>Lag5</id>
<id>Tag6</id><id>Lag6</id>
<id>Tag7</id><id>Lag7</id>
</root>'

select t.c.value('.','varchar(100)') as string
  From @xml.nodes('root/id/text()') As t(c)

UDF 的执行计划: https ://www.brentozar.com/pastetheplan/?id=SJpX2DMwi

XML 的执行计划: https ://www.brentozar.com/pastetheplan/?id=ByQv2PMvo

sql-server
  • 1 1 个回答
  • 77 Views

1 个回答

  • Voted
  1. Best Answer
    J.D.
    2022-11-29T09:40:16+08:002022-11-29T09:40:16+08:00

    udfs 会导致很多性能问题

    这不一定是真的。糟糕的代码无论放在哪里都会导致性能问题。但是某些类型的 UDF 有一些缺点:

    1. 直到 SQL Server 2019,标量函数运行 RBAR(逐行),其中某些标量函数是 inlinable。
    2. 标量函数可防止直接引用它们的任何对象或调用堆栈任何部分的任何依赖对象的任何计划中的并行性。
    3. 多语句表值函数可防止查询计划中引用它们的区域中的并行性。

    最好的做法是通常不使用标量函数,因为它们有很多缺点,而单语句表值函数就很好。多语句表值函数问题较少,因为它们仅在查询计划中引用它们的地方被序列化,但整个查询计划仍然可以有其他并行化区域。

    如需进一步阅读有关 SQL Server 中并行性抑制的内容,请参阅 Paul White 的文章Forcing a Parallel Query Execution Plan 。

    我想知道 XML 是否真的比多表 UDF 好,如果是,是什么让它更好?

    与大多数性能问题一样,我想说这完全取决于您使用 XML 与多语句表值函数进行的操作。使用您提供的执行计划,快速浏览一下,似乎 MSTVF 的性能可能更好(因为它处理的数据更少,并且通常只是一个更简单的执行计划,步骤更少)。但我不能下定论。

    您可以将事件探查器或扩展事件与 SQL:BatchCompleted 事件一起使用,或者运行SET IO, TIME STATISTICS ON并查看MessagesSSMS 中的窗口以查看CPU Time、Elapsed Time和其他TIME STATISTICS,并IO STATISTICS帮助衡量哪个执行效率更高。具有 less CPU Time、 lowerElapsed Time和/或 lessLogical Reads的是您可以用来确定哪个性能更高的一般因素。

    此外,Erik Darkling 建议在过程中使用表值参数通常是一个很好的做法。这将是我的 3 个选择中的首选。

    表值参数是否比 XML 或字符串解析有任何优势?

    是的,数据已经以表格格式呈现,不需要(在 SQL Server 上)处理就可以到达那里。使用它们唯一明显的缺点是它们作为一个表变量出现,SQL Server 不对其维护统计信息。我通常的解决方法是立即SELECT将表变量放入临时表,然后在整个过程中使用该临时表。


    我们仍在使用 SQL Server 2012

    我强烈建议尽快升级,因为它落后于最新的四个主要版本,并且也不再受 Microsoft 支持。延长支持日期于去年 7 月(2022 年)结束。

    • 4

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve