如何避免对sum()重复调用cpu密集函数?

时间:2014-06-10 15:01:14

标签: sql sql-server

我有一个函数对传递的id执行cpu繁重的计算 我正在编写一份报告来总结结果,但出于性能原因,我只希望每个id调用一次该函数

这是一个简单的工作SQL示例,它为每列调用一次函数。如何重写查询以仅为每个标识符调用一次函数?

    SELECT 
    SUM( case myfunction(employee_id) WHEN 'bob' THEN 1 ELSE 0 END) as "bob total",
        SUM( case myfunction(employee_id) WHEN 'joe' THEN 1 ELSE 0 END) as "Joe total",
    SUM( case myfunction(employee_id) WHEN 'tom' THEN 1 ELSE 0 END) as "Toms total"
    FROM employee

3 个答案:

答案 0 :(得分:1)

您可以在执行求和之前将逻辑放在子查询中,然后引用单列。

SELECT 
    SUM( case FunctionResult WHEN 'bob' THEN 1 ELSE 0 END) as "bob total",
    SUM( case FunctionResult WHEN 'joe' THEN 1 ELSE 0 END) as "Joe total",
    SUM( case FunctionResult WHEN 'tom' THEN 1 ELSE 0 END) as "Toms total"
FROM    
    (   SELECT myfunction(employee_id) AS FunctionResult
        FROM employee
    ) AS e;

在性能方面更好的解决方案是查看标量函数实际执行的操作,并问自己是否需要成为函数,是否可以基于解决方案设置?

答案 1 :(得分:0)

使用如下定义的派生表而不是FROM employee

SELECT *, myfunction(employee_id) AS myFuncResult
FROM employee

现在,您有myFuncResult作为附加列。让我们希望优化器不会混淆这种策略。它对标量函数成本没有很好的理解(事实上,没有)。

答案 2 :(得分:0)

由于您使用的是SQL Server,您可以尝试使用CROSS APPLY表达式,只需将.Result替换为函数返回的列的名称:

SELECT 
    SUM( case func.Result WHEN 'bob' THEN 1 ELSE 0 END) as "bob total",
    SUM( case func.Result WHEN 'joe' THEN 1 ELSE 0 END) as "Joe total",
    SUM( case func.Result WHEN 'tom' THEN 1 ELSE 0 END) as "Toms total"
FROM employee e
CROSS APPLY myfunction(e.employee_id) as func