SQL Server 2008R2自定义函数如此之慢

时间:2014-03-24 17:05:43

标签: sql sql-server sql-server-2008-r2

这是我的功能:

-- DECLARE @cur CURSOR
DECLARE @line int
declare @return varchar(255)

DECLARE myCursor CURSOR FOR
SELECT DISTINCT (quote_ln_no) as quote_ln_no
  FROM dbo.quote_line_bom
 WHERE quote_no = @quote_no AND component_mat_no = @mat_no
ORDER BY quote_ln_no

set @return = ''

OPEN myCursor

FETCH NEXT FROM myCursor
INTO @line
WHILE @@FETCH_STATUS = 0
BEGIN
  set @return = @return + convert(varchar, @line) + ', '
  FETCH NEXT FROM myCursor 
  INTO @line
END

CLOSE myCursor
DEALLOCATE myCursor 

if len(@return) > 0 
set @return = substring(@return, 1, len(@return)-1)

return @return

当我在返回超过3000条记录的查询中使用此函数时,函数会增加20秒。

请让我知道它有什么问题,或者有办法让它运行得更快吗?

2 个答案:

答案 0 :(得分:1)

我认为这会更快。它是基于集合的,不使用游标。

DECLARE @return VARCHAR(255) = ''

SELECT @return = @return + CAST(quote_ln_no AS VARCHAR) + ','
FROM dbo.quote_line_bom
WHERE quote_no = @quote_no AND component_mat_no = @mat_no
AND quote_ln_no IS NOT NULL
GROUP BY quote_ln_no
ORDER BY quote_ln_no

IF LEN(@return) > 0 
    set @return = SUBSTRING(@return, 1, LEN(@return)-1)

SELECT @return

--This is for a user defined function, right?
--RETURN @return

答案 1 :(得分:0)

您可以使用COALESCE代替光标:

declare @return varchar (255) = ''

select
@return = coalesce(@return + ' ', '') + quote_ln_no
FROM dbo.quote_line_bom
WHERE quote_no = @quote_no AND component_mat_no = @mat_no
ORDER BY quote_ln_no

你可以加入它,但是我只是使用交叉申请,因为我很懒。 这是一个非常粗糙的例子: SQLFiddle

编辑: 我没有足够的聪明才能弄清楚如何在子查询中使用coalesce,但我确实研究了如何使用XML方法来实现它。

您的查询将如下所示:

select <some stuff>
from
<some tables>
cross apply
(select quote_ln_no + ' '
 FROM dbo.quote_line_bom
    WHERE quote_no = @quote_no AND component_mat_no = @mat_no
) t1 (quote_ln_no)
...

另一个粗略的例子: XML example