【发布时间】:2015-08-27 11:22:49
【问题描述】:
我的看法如下:
CREATE VIEW V1
AS
SELECT
T1.Col1, F1.Col1, T1.Col2, T2.Col2...
FROM
T1
INNER JOIN
T2 ON T1.Col2 = T2.Col1
CROSS APPLY
UDF(T1.Col1, T2.Col2) F1
内连接返回百万条记录。在这里,在这种情况下,我知道 T1.Col1 的确切值,它将从应用程序传递。
有没有办法重写上面的视图,使交叉应用可以只应用于过滤的记录(基于T1.Col1值),而不是处理所有记录,然后再过滤?当前视图即使在 20 分钟后也不会返回任何值,而当我将值直接传递给 UDF 时,它会在不到一秒的时间内返回输出。
更新: 以下是 UDF 的结构,我根据以下 cmets 更新了问题:
CREATE FUNCTION [dbo].[UDF](@Col1 INT, @Col2 INT)
RETURNS @TBL TABLE(Col1 int, Col2 int, Col3 VARCHAR(10), Col4 int) AS
DECLARE CURSOR1 CURSOR FOR
SELECT DISTINCT Col1 FROM TBL1 WHERE Col2 = @Col1 AND Col3 = @Col2
OPEN CURSOR1
FETCH NEXT FROM CURSOR1 INTO @Col1
WHILE (@@FETCH_STATUS = 0)
BEGIN
DECLARE CURSOR2 CURSOR FOR...
INSERT INTO @TBLVAR
SELECT * FROM SRCTBL1 WHERE
CLOSE CURSOR2
DEALLOCATE CURSOR2
DECLARE CURSOR3 CURSOR FOR...
INSERT INTO @TBLVAR
SELECT * FROM SRCTBL2 WHERE
CLOSE CURSOR3
DEALLOCATE CURSOR3
DECLARE CURSOR4 CURSOR FOR...
INSERT INTO @TBLVAR
SELECT * FROM SRCTBL3 WHERE
CLOSE CURSOR4
DEALLOCATE CURSOR4
CLOSE CURSOR1
DEALLOCATE CURSOR2
SELECT Col1, Col2, Col3, Col4
【问题讨论】:
-
你可以将UDF代码合并到查询中sqlblog.com/blogs/hugo_kornelis/archive/2012/05/20/…
-
如果您可以将视图转换为内联 TVF,您将能够在 T1.Col1 上传递参数和过滤器。但是,我担心UDF本身正在扼杀性能,有没有办法内联它?
-
恐怕UDF不能内联。它包括 4 个游标,其中一个父游标在其中处理 3 个以上。每个游标都有一个复杂的逻辑。我想,我们需要将完整的 UDF 重写为单独的 UDF。但是,同样在这种情况下,我不确定性能改进。
-
你真的有 4 个光标在这个东西上?从您发布的骨架看来,您正在使用游标进行插入。更糟糕的是,听起来你有嵌套的游标。只有一种方法可以解决此问题。删除这些光标并使您的函数集基于。我愿意打赌所有这些游标都可以用基于集合的逻辑替换,性能问题也会消失。
-
@SeanLange Insert 在所有游标中都很常见,其中两个也具有基于条件的更新。它有 7 年历史的遗留脚本根据需要进行了更新,现在看起来像第一次面对我的怪物 :)。我只是想过滤掉连接返回的记录,如果可能的话,这样就至少没有了。对十字架的呼吁适用。我想现在我必须重写整个事情。告诉我一件事,如果我可以使每个光标内联并从父级调用它们,性能会受到严重影响吗?
标签: sql-server performance views cross-apply