0

我创建了一个 Linq to Entities 并使用了

Enumerable.Distinct<T>(this IEnumerable<T> source, IEqualityComparer<T> comparer)

在查询中。

由于我的“比较器”类,查询在客户端运行。它按预期工作,我得到了想要的结果,但是查询很慢,因为所涉及的表有很多行,所以我在想是否可以使用 SQL CLR 来实现整个查询,包括 Comprarer 类,整个查询运行在服务器端。

可能吗?

欢迎任何想法。

4

2 回答 2

2

SQL 2005 CLR 默认只支持 .Net 2.0 框架。我之前已经将 .Net 3.5 框架导入 SQL Server,但它有点混乱并打开了一些安全漏洞(不记得所有细节),但这个问题快速而肮脏- 特别是

CREATE ASSEMBLY [System.Core]
AUTHORIZATION [dbo]
FROM 
'C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll'
WITH PERMISSION_SET = UNSAFE

您在 CLR 过程中通常遇到的另一个障碍是运行存储过程的用户的安全上下文不是由 CLR 过程继承的,因此尝试完成某些事情可能比您预期的更难。

调试 CLR proc 并不容易。你可以做到,而且我永远无法获得完整的堆栈回溯(带有行号等)。因此,尽可能在将其移至 CLR 之前进行调试。

除此之外,我在 CLR proc 上没有遇到太多麻烦——只要你通过在 SQL 中运行复杂的代码来处理可能的性能问题,它们就可以很好地工作,不要在 CLR proc 中分配大量内存——你会后悔的。

添加

我想到的另一个问题。CLR proc 代码编写需要比典型的客户端代码或存储过程更高的熟练程度。这是维护方面的考虑。

对 CLR proc 的更新也使客户端代码或 sql procs 更复杂,因此这也可能是一个问题。这也使维护复杂化。

我并不是要阻止 CLR procs,好处也很好——性能、灵活性、安全性(必须具有数据库权限才能更新)。但是,当您阅读“CLR procs 是多么伟大和简单”时,我试图记录他们没有告诉您的问题。

添加

您没有提供详细信息,但是如果您是数据绑定的(很多行)并且您可以将逻辑编写为基于集合的 TSQL 性能几乎肯定会比基于集合的要好得多。如果您尝试通过 TSQL 进行大量计算,TSQL 会很慢——脚本运行速度很慢,数据库 I/O 运行速度很快。TSQL 作为一种编程语言不是很灵活,因此 CLR 增加了灵活性和更快的代码执行速度。

如果您不熟悉在 select 语句(Sql 2005+)中使用 APPLY,您应该花时间理解,因为它对于保持复杂查询“基于集合”非常有用——您永远不想使用如果可以避免,则使用游标——速度慢并占用数据库资源。

于 2013-11-13T21:04:45.230 回答
1

您可能会节省一些通过网络发送结果的拖累,但如果您在 1 GB 网络上,那么这可能并不重要,特别是因为它对于“吨行”的含义相当模糊。我们说的是数十万还是数百万?

在任何一种情况下,我都不确定这里是否清楚地了解 SQL CLR 基于语句“使用 SQL CLR 实现包括 Comprarer 类的整个查询,以这种方式整个查询在服务器端运行”。您不能在 SQL CLR 中编写查询。创建 .Net / CLR 存储过程和函数不会取代 T-SQL 与数据库交互。这意味着您仍然需要执行 SELECT 语句并返回结果。在 SQL CLR 对象中使用 LINQ to SQL 仍将像现在从客户端执行相同的 SQL。

如果提供了有关进行比较的最终目标的更多详细信息,则可以计划更合适的解决方案。但考虑到所提出的问题,将这段代码移动到 SQL Server 中似乎值得怀疑,假设仍然在 .Net 代码中进行比较,是否会提供很多好处(如果有的话)。

编辑:更清楚一点:将业务逻辑转移到运行服务器端,以避免将所有行拉入内存,以便可以通过自定义比较器进行比较,这需要您创建一个 SQL CLR 函数并使用它在 WHERE 子句中。因此,模型将被更改为基本上一次将一行发送到函数进行比较,而不是在集合中全部可用。

于 2013-11-13T21:43:11.613 回答