Eri*_*ing 31 sql-server parallelism functions computed-column
已经有很多关于SQL Server中标量 UDF的危险的文章。随意搜索将返回大量结果。
不过,有些地方标量 UDF 是唯一的选择。
例如:处理 XML 时:XQuery 不能用作计算列定义。Microsoft 记录的一种选择是使用标量 UDF将 XQuery 封装在标量 UDF 中,然后在计算列中使用它。
这会产生各种影响和一些解决方法。
您可以通过对函数进行架构绑定来绕过逐行执行,并保留计算列或对其进行索引。即使未引用标量 UDF,这两种方法都不能阻止强制序列化查询表。
有没有一种已知的方法可以做到这一点?
Pau*_*ite 33
是的,如果您:
PERSISTED具体来说,至少需要以下版本:
但是为了避免这些修复中引入的错误(参考2014 年,以及2016 年和 2017 年),改为应用:
跟踪标志作为启动–T选项是有效的,在全局和会话范围内使用DBCC TRACEON,以及每个查询OPTION (QUERYTRACEON)或计划指南。
跟踪标志 176 可防止持久计算列扩展。
编译查询时执行的初始元数据加载会引入所有列,而不仅仅是直接引用的列。这使得所有计算列定义都可用于匹配,这通常是一件好事。
一个不幸的副作用是,如果加载的(计算的)列之一使用标量用户定义函数,它的存在会禁用整个查询的并行性,即使实际未使用计算列也是如此。
跟踪标志 176 通过不加载定义(因为跳过扩展)来帮助解决此问题,如果该列被持久化。这样,编译查询树中永远不会出现标量用户定义函数,因此不会禁用并行性。
跟踪标志 176 的主要缺点(除了只是很少记录)还阻止查询表达式匹配持久计算列:如果查询包含匹配持久计算列的表达式,跟踪标志 176 将阻止表达式被替换为对计算列的引用。
有关更多详细信息,请参阅我的 SQLPerformance.com 文章正确持久化计算列。
由于该问题提到了 XML,作为使用计算列和标量函数提升值的替代方法,您还可以考虑使用 Selective XML Index,正如您在Selective XML Indexes: Not Bad At All 中所写的那样。
Sol*_*zky 12
除了@Paul 出色的Yes #1 之外,实际上还有一个Yes #2:
PERSISTED,和唯一的缺点(据我所知)是:
这个选项是:SQLCLR
这是正确的。SQLCLR 标量 UDF 的一个很酷的方面是,如果它们不进行任何数据访问(无论是用户还是系统),它们都不会禁止并行性。这不仅仅是理论或营销。虽然我没有时间(目前)做完整详细的文章,但我已经测试并证明了这一点。
我使用了以下博客文章中的初始设置(希望 OP 不会认为这是一个不可靠的来源):
并进行了以下测试:
([c2] * [c3])?? 并行性(如预期)SCHEMABINDING定义为RETURN (@First * @Second);?? 无并行性(如预期)IsDeterministic = true和= false定义为)return SqlInt32.Multiply(First, Second);?? 平行性(呜呜!!)因此,虽然 SQLCLR 并不适用于所有人,但它对于那些非常适合的人/情况/环境肯定有其优势。并且,由于它与这个特定问题有关——给出的示例是关于使用 XQuery 的——它肯定会为此起作用(并且,取决于具体正在做什么,它甚至可能更快一点)。
| 归档时间: |
|
| 查看次数: |
2699 次 |
| 最近记录: |