16

我已经在 SQL Server 中使用 CLR 存储过程有一段时间了,但我仍然想知道使用它们的最佳情况是什么。

MSDN 提供了一些使用指南,例如繁重的字符串操作 (regex),或替换声明大量表变量和游标的 T-SQL。我很想知道 SO 用户使用 CLR 存储过程以及示例/基准测试解决了哪些问题。

例如,我发现 CLR 存储过程 + SSRS 是一种很好的方法,可以将数据操作逻辑从 SSRS 和 T-SQL 中提取出来,并将其放入更易于阅读和操作的托管代码中。

4

6 回答 6

23

许多需要非规范化和/或顺序操作的问题可以由 CLR 处理得非常好,并且可以用来显着提高性能而不会牺牲 SQL 端的可用性(很多)。与其完全依赖基于集合或迭代的操作,您可以采用混合方法,对大型运输使用基于集合的解决方案,并为紧密循环切换到迭代模型。

SQL Server 2008 中的内置hierarchyid和地理空间(即geography)类型是非规范化问题的好例子。两者都包含(几乎)任意大量的数据,这些数据难以在不影响性能的情况下进行标准化 - 您需要使用递归或游标来对它们进行任何有意义的工作,或者使用老鼠巢的触发器和/或计划任务来维护一个非规范化表。

我用 CLR 类型解决的另一个问题是内联压缩。这听起来像是毫无意义或学术性的练习,但是当您的完全规范化的数据进入 TB 级时,大小减少 80-90% 意味着很多。SQL 现在有自己的内置压缩,SQL 2005 有 vardecimal,这些也是很好的工具,但是域感知“最小化”算法在 CPU 负载和压缩率方面的效率可以提高几倍。显然,这并不适用于所有问题,但它适用于一些问题。

在此站点上经常发现的另一个非常常见的问题是动态生成序列 - 例如连续日期的序列。常见的解决方案是递归 CTE、静态序列表和鲜为人知的spt_values表,但简单的 CLR UDF 比它们中的任何一个都执行得更好,并且提供了更多的灵活性。

最后在我的列表中:用户定义的流聚合也非常有用,特别是对于任何与统计相关的东西。有些东西你根本无法从内置 SQL 聚合中组合出来,例如中位数、加权移动平均线等。UDA 也可以接受多个参数,因此你可以将它们参数化;从技术上讲,不能保证聚合在当前版本的 SQL Server 中以任何特定顺序接收数据,但是您可以通过将它ROW_NUMBER作为附加参数提供并使用它来实现几乎任何窗口函数(具有聚合吐出一个 UDT,然后可以将其转换为表)。

真正有用的 SQL-CLR 应用程序的示例很少,这实际上非常令人沮丧。在 Google 上搜索,你会得到 1000 万条结果,其中每一条都是一些愚蠢的字符串连接或正则表达式。这些很有用,但需要花几分钟时间来了解 SQL UDT 和 UDA,尤其是您将开始在自己的应用程序中看到它们的大量用途。当然,不要发疯——仔细考虑在纯 SQL 中是否有更好的解决方案——但也不要打折扣。

于 2010-01-26T19:50:19.463 回答
5

字符串操作——正则表达式搜索是经典。在 CLR 中很容易暴露,在直接的 T-SQL 中很难做到。

有关实现的详细信息和微基准 ( ) ,请参阅此链接。SQLCLR is only 47 milliseconds compared to 6.187 seconds for the T-SQL UDF

于 2010-01-26T17:03:28.903 回答
5

已经提到了字符串操作(正则表达式),还有 DateTime 算法,当然还有另一个大问题 - 调用外部 Web 服务。

于 2010-01-26T17:06:07.150 回答
3

这是我使用 CLR procs 的一个例子,我认为它很简洁:

使用 CLR 存储过程和 SQL 作业从外部 Web 服务定时更新数据。

我们有一个应用程序,可以将它跟踪的一些数据与外部行业数据馈送同步。每周同步运行所有内容,也按需运行单个更新,因此我有一个现有的 Web 服务 API 来访问它。Windows 服务已经安排了事情,但我想为什么不能像我们的其他 SQL 作业一样安排它们?

我创建了一个引用应用程序的 Web 服务 API 的 CLR 存储过程。然后我为@RecordID 添加了一些参数以支持单同步,并将其安排在企业管理器 SQL 作业中。

现在我可以使用 Job 来运行 dB 同步或使用其他 SQL procs 或 Triggers 中的 proc 来更新来自外部提要的数据。

以后把应用程序的 webservice API 拿出来,直接使用外部的 webservice 可能会更干净。不过就目前而言,这实现起来非常快,并且是一种将功能扩展到 SQL 组的好方法。

于 2010-01-27T19:44:02.483 回答
2
  • 自定义聚合
  • 字符串操作
  • 自定义数据类型

老实说,我只看到字符串处理,其中包括将 CSV 拆分为行。

除非我是从事 DBA 类型工作的 DBA,否则我认为任何需要超过默认信任级别的东西都超出了界限。

来自 MSDN 的 RegEx 和 RSS 提要示例:在 SQL Server 2005 中使用 CLR 集成

于 2010-01-26T18:32:22.850 回答
1

对于从不提供传统 SQL 接口或供应商对该接口的实现低于标准的系统中提取数据非常有用。

我们有一个在旧 MUMPS 平台上构建的核心应用程序,在 Intersystems Cache 数据库上运行。数据是分层的,而不是本质上的关系。主全局数组(即表)具有多个数据级别和元素,所有这些都按帐号分组。即使扫描一列也需要从磁盘加载整个全局,并且需要 8 多个小时。供应商确实提供了 ODBC 驱动程序和全局映射,但它通常会导致扫描和极慢的查询。

我构建了一个表值函数,该函数采用 ObjectScript(跨系统的 MUMPS 方言)程序,在缓存服务器上执行它并将输出行作为数据行返回。我可以在 MUMPS 端对数据访问路径进行微观管理(这确实是获得高效数据访问所需的),方法是提供一个特定的程序在该端执行,然后轻松地将 MSSQL 中的数据作为临时内联数据源导入。

我可以使用 TVF 来驱动数据选择或用于CROSS APPLY在另一端进行查找,而且效率相当高。如果我强制 MSSQL 使用并行执行计划,我什至可以在远程端并行运行多个查询。

于 2013-01-29T16:24:20.430 回答