【发布时间】: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