【问题标题】:How Can CLR Be Leveraged In Place of T-SQL Functions to Avoid RBARs?如何利用 CLR 代替 T-SQL 函数来避免 RBAR?
【发布时间】:2016-07-16 18:34:26
【问题描述】:

我需要在一些 SQL Server 数据集上重复执行一些简单的函数,例如重载、二进制步骤、sigmoid 和各种切线。我经常听说,通过 T-SQL 派生在此类函数中使用的任何集合和聚合是有效的,但在 T-SQL 中重复执行此类函数则效率低下。根据 SQL Server 大师 Jeff Moden 的流行术语,根据我所读到的内容,将 T-SQL 用于此目的显然可以称为“RBAR”操作,或“Row by Agonizing Row”。在散布在互联网上的各种文章中,我经常读到这样的功能应该在 C# 或 VB.Net 中实现,但我不清楚我究竟如何才能做到这一点并且仍然避免 RBAR。谁能指出一些为此目的使用 .Net 语言的最佳实践?这引发了一些密切相关的问题,例如:

1) 我可以在 CLR 函数中有效地做到这一点吗?

2) 在此类函数中使用 C# 或 VB.Net 数组并为它们提供整组数据会更有效吗?

3) 如果我仍然为集合中的每条记录调用一次 CLR 函数,就像使用普通 SQL Server 函数一样,我如何在这种设计中避免 RBAR?

4) 是否应该在中间层对象中捕获此类逻辑并通过网络提供数据?

5) 如果我必须整天偶尔批量执行这些功能,我可以在服务器端运行 C# 或 VB.net 程序并不断地为其提供数据吗?此解决方案可能与 #2 一起使用,但我认为如果允许消耗 SQL Server 无法控制的过多内存/CPU/IO,它可能会损害服务器稳定性。

这些问题的全部重点主要针对一个目标:在执行这些功能时找到避免 RBAR 的最有效方法。如果还有其他我没有提到的避免它们的方法,请告诉我。我已经知道如何通过使用 T-SQL 创建聚合和基于集合的解决方案来避免某些 RBAR,但我想知道是否可以消除与重复函数调用直接相关的任何其他问题。最佳实践似乎是使用 .Net 而不是 SQL Server 函数来实现这一点,但我不清楚如何在实践中实现它。为我澄清这个设计决定时,我们将不胜感激。

【问题讨论】:

  • 分析函数是这里的罪魁祸首。你不能使用表格函数吗?转换和转换是每行运行多个查询的小成本。你确定这仍然是一个关系问题吗?然后使用 SQL。这是草书,然后使用适当的方法(如 .Net,虽然 SQL 有自己的方法)。如果你说的是真的,我想我不明白你是如何进行“简单”计算的
  • 是的,这绝对是相关的,因为在将这些简单的数学函数(如各种 step 和 sigmoid,例如逻辑函数 - 参见 en.wikipedia.org/wiki/Logistic_function)应用到每一行之前,我必须导出一些复杂的集合。我没有为此使用表格函数的原因是我仍然必须为其中的每一行(RBAR)执行一次数学函数,所以它根本无助于优化我的事情。我可以轻松地在 T-SQL 中编写自己的逻辑函数,但我听说在 C# 或 VB.Net 中执行这种类型的事情会更有效。
  • 我可能会感到困惑。我的意思是关系数据集。集合论。 T-SQL 确实有草书操作(包括 XQuery。OPENXML 使用集合),但是是的,使用草书语言处理草书逻辑可能更有效。
  • 你能举一个这些函数的例子吗,比如,特别是在代码中(伪或其他)?如果您只需要对一组字段运行算术运算,通常可以“内联”完成(意味着 SQL 可以为您的函数替换适当的代码),而不必在每一行上完全执行该函数。如果你有比这复杂得多的东西,那么 CLR 可能值得考虑。但是请记住,CLR 带有大量的陷阱和潜在的安全问题,这些问题很难完全解决或克服 DBA。
  • 至于 CLR 是否会比 t-sql 更快的单一问题,这取决于您必须通过测试来解决这个问题。 8k ascii 或 4k unicode 下的经典字符串拆分通过 CRL 稍微快一点,这真的不值得。解析大型 JSON 字符串(pre sql 2016),值得。如果性能很重要,请花时间同时做这两件事,并将结果与​​具有实际值的大型数据集进行比较。

标签: sql-server tsql clr


【解决方案1】:

没有。 CLR 只是一个用 .Net 编写并在 SQL Server 中公开的函数,因此 SQL 引擎可以调用它。它们通常比优化的 SQL 查询效率低,但允许您执行 SQL 无法执行的操作,例如高级字符串操作或分析计算。作为副作用,CLR 允许 Web 程序员创建在 SQL 对他们来说是陌生的情况下有意义的代码,但同时也避免了 SQL 基于集合(非 RBAR)的高效操作。

如果您的计算是针对整个数据集的,例如在松鼠数据库中查找平均松鼠体重,您可以使用基于集合的聚合来获取 CLR 函数 (SELECT AVG([Weight]) FROM dbo. SQUIRRELS),但是如果您需要对数据中的每一行进行计算,那么如果 SQL 无法进行计算,您就会陷入困境。

如果您可以使用 SQL 执行计算,您应该创建一个执行计算的内联表值函数,然后使用 OUTER APPLY 更新计算字段。如果您想研究这条路线,这里有一个解释。 Rob Farley's SQL Blog.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-08
    • 1970-01-01
    • 2012-10-06
    • 1970-01-01
    • 2010-09-06
    • 2017-08-07
    • 2018-09-08
    • 1970-01-01
    相关资源
    最近更新 更多