使用SQL CLR在服务器端运行客户端查询

时间:2013-11-13 20:54:25

标签: c# sql-server linq

我已经创建了Linq to Entities并且我已经使用了

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

在查询中。

由于我的&#34; Comparer&#34;将查询分类在客户端运行。它按预期工作,我得到了所需的结果,但查询很慢,因为涉及的表有很多行,所以我在想是否可以使用SQL CLR以这种方式实现整个查询,包括Comprarer类整个查询在服务器端运行。

有可能吗?

欢迎任何想法。

2 个答案:

答案 0 :(得分:2)

SQL 2005 CLR默认只支持.Net 2.0 framwork。我之前已经将.Net 3.5框架导入到SQL服务器中,但是它有点凌乱并且打开了一些安全漏洞(不记得所有细节),但是快速而肮脏的是in this question - 特别是

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过程没有太大的麻烦 - 只要你通过在SQL中运行复杂的代码来处理可能的性能问题,它们就能很好地工作,不要在你的CLR中分配大量的内存proc - 你会后悔的。

ADDED

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

CLR proc的更新也比客户端代码或sql proc更复杂,所以这也可能是个问题。这也使维护变得复杂。

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

ADDED

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

如果你不熟悉在select语句(Sql 2005+)中使用APPLY,你应该花时间去理解,因为它对于保持复杂查询“基于集合”非常有用 - 你不需要如果可以避免使用游标,请使用游标 - 减慢并咀嚼数据库资源。

答案 1 :(得分: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子句。因此,模型将被更改为基本上一次向函数发送一行以进行比较,而不是在集合中全部可用。