2009-07-03 67 views
4

我有一个相当庞大的查询需要在几个存储过程中,我想将它转换为一个UDF,以便更容易维护(视图将无法工作,这需要一堆参数),然而,我曾与之交谈过的每个人都告诉我,UDF的速度非常慢。虽然我不知道究竟是什么使它们变慢,但我会猜测它们是,但是由于我在连接中不使用此UDF,而是返回表变量,所以我认为它不会那么糟糕。SQLServer:为什么要避免表值用户定义函数?

所以我想问题是,我应该不惜一切代价避免UDF?任何人都可以指出具体的证据表明他们更慢?

+0

你可以发布一些或所有你所问的UDF吗?它是内联表UDF还是多行? – 2009-07-04 00:01:04

+0

多行UDF,但不能发布代码。 – FlySwat 2009-07-04 00:37:35

+0

UDF似乎变得糟糕的说唱。我们广泛使用表值UDF来针对大数据集进行一些复杂的计算。表现非常出色。我们的许多UDF也是多线的,在我们的案例中,似乎并不影响性能。 – 2009-10-21 21:15:07

回答

-2

是否有某些原因,您不想使用stored procedure而不是UDF?

+0

主要是因为你不能在SQLServer中做到这一点,所以你必须将sproc的返回插入到临时表中。 – FlySwat 2009-07-03 23:20:47

+0

对不起,SQL Server中不能做什么?存储过程可以调用另一个存储过程。 – 2009-07-03 23:55:46

3

正如您所指出的,(表格)udf的结果将不会加入任何内容,那么不应对性能产生任何影响。

为了试图解释一下为什么UDF可以被认为是很慢的(实际上只是以错误的方式使用),请考虑下面的例子;

我们有表A和B表假设我们有一个像

联接选择 A.col1, A.col2, B.ColWhatever FROM 一个 JOIN B ON A.aid = B .fk_aid WHERE B.someCol = @参数1和A.anotherCol = @参数2

在这种情况下,SQL Server将做到这一点,最好在它知道如何最高效的方式返回结果。其中一个主要因素是减少磁盘读取。因此 - 它将使用JOIN和where子句中的条件来评估(希望通过索引)返回多少行。

现在 - 比方说我们提取了一部分用来抵消返回给UDF的数据的条件。现在 - 查询优化器不能再从磁盘中取回最小数量的行,它只能处理它提供的条件。简而言之 - 一个表udf总是被评估,并且在返回到主sproc之前返回数据,因此,如果原始联接中还有其他一些标准可能会导致更少的磁盘读取 - 这只会应用于数据被拉入存储器后。

所以说,我们创建一个UDF来选择表B中匹配where子句的行。如果表B中有100k行,并且其中50%符合where子句的条件,则所有这些行将返回到存储过程以与表A比较。现在如果只有10%的人在表A中有匹配,那么现在我们只与我们想要合作的B表的5%进行对话,但我们已经拉回了50%,其中大部分我们不想要!

如果这是作为完整的胡言乱语道歉 - 请让我知道!

0

你可以发布你的代码吗?一般来说,如果您在查询的select子句中使用标量udf,则udf中的语句将在查询返回的每行中执行一次。对一个udf表进行联接会更好,或者找到某种方法在你的udf中使用主SQL语句中的联接执行逻辑。

相关问题