sql-server - 内联表值 UDF 性能

标签 sql-server inline sql-server-2008-r2 user-defined-functions

我正在使用 SQL Server 2008R2。我编写了以下表值 UDF,它接受标量值 this 或 that 或两者作为参数,并返回一个包含列 ID、this 和 that 的表。当我从一个复杂的查询中调用这个函数时,我看到了糟糕的性能,但当我在简单的查询中调用它时却没有。我想知道是否有人对我正在做的事情有任何想法,这会减慢速度。函数定义如下:

CREATE function dbo.fn_getThisThat (@this nvarchar(255), @that nvarchar(255))
RETURNS TABLE
RETURN

SELECT These.this, Those.that, COALESCE(These.ID, Those.ID) as ID
FROM 
    (
    SELECT col1 as ‘this’, value1, value2, ID
    FROM (
        SELECT t1.col1, t1.col2, t1.col3, t2.col1
        FROM t1
        JOIN t2
            ON t1.col1 = t2.col1
        WHERE t2.col2 = ‘this’
        AND t1.col1 in (‘value1’, ‘value2’)
        ) SOURCE
    PIVOT (
        MAX(t1.col3) FOR t1.col1 in (value1, value2)
        ) AS pvt
    ) These
JOIN
    (
    SELECT t1.col1, t1.col2, t2.col1, t3.ID
    FROM t3
    JOIN t1
        ON t3.col1 = t1.col1
    JOIN t2
        ON t2.col1 = t1.col1
    WHERE t3.col3 = ‘value3’
    AND t1.col3 = ‘value1’
    AND t2.col3 = ‘value2’
    ) Those
WHERE that = @that
OR this = @this

传递标量参数时,以下语句处理速度非常快(< 1 秒):

SELECT * FROM dbo.fn_getThisThat(scalarValue, null)

或者在一个相对简单的查询中,例如:

SELECT t1.col1, t1.col2, fn.This
FROM t1
CROSS APPLY dbo.fn_getThisThat(t1.col3, null)

…但是当在像这样的更复杂的查询中调用时,它会非常滞后(从处理时间 ~1 秒到 ~2:30 秒)(伪代码:如果信息不足请告诉我):

DECLARE @table (a, b, c)
INSERT @table (a, b, c)
SELECT (values)

SELECT t1.c1, t1.c2, t1.c3
FROM
    (
    SELECT a.c1, COUNT(fn.That) as c2, COUNT(a.c2) as c3
    FROM a
    JOIN b ON (join terms)
    CROSS APPLY dbo.fn_getThisThat(a.c2, null) fn
    WHERE a.c1 IN (SELECT a FROM @table)
    GROUP BY a.c1
    ) t1

有没有人对我正在做的事情来降低第二个查询的速度有什么建议?我更改了函数以接受数组而不是标量参数,但这消除了我交叉应用的能力(在最后一个代码片段中)。据我从查询分析器中可以看出,性能下降来 self 的函数的交叉应用。我以为我不会遇到 RBAR,因为我的 UDF 不是多语句的,但也许我大错特错了……?

编辑: 还有一点:查询执行计划显示函数本身对批处理的贡献只有 2%;较大的查询贡献了 98%,但其大部分成本来自索引查找和表扫描,而不是来自并行性。这让我觉得,也许函数调用并不是查询缓慢的罪魁祸首,而是涉及的一些表缺乏索引(不幸的是,我对添加指数)。我在没有调用函数的情况下运行查询,表扫描和索引查找仍然显示很高,但查询在大约 8 秒内完成。那么,我们回到函数...?

最佳答案

您可能希望更改您的 UDF 以在任何地方正确使用由两部分组成的表名,以便您可以向其添加 SCHEMABINDING 子句。参见 Improving query plans with the SCHEMABINDING option on T-SQL UDFs .

关于sql-server - 内联表值 UDF 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6918137/

相关文章:

sql-server - 将 'current' 行传递给 SQL Server 中的函数

css - 如何让 <select> 显示内联?

sql - 选择列名为 "index"的表

sql - 在 CASE 语句中使用 CAST 时出现数据转换错误

sql - MS SQL Server - 如何从 CTE 创建 View ?

PHP - Thunderbird 中不显示内联图像

html - 如何在 twitter bootstrap 中排列我的按钮

sql - DateAdd 列导致溢出

sql-server-2008-r2 - sql server 2008 R2 Management Studio 表娱乐

java - 无法使用 HQL 从我的 Java 应用程序查询包含阿拉伯语的 SQL Server 表