简体   繁体   English

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

[英]how to avoid calling cpu intensive function repeatedly for sum()?

I have a function that performs a cpu heavy calculation on a passed id I am working on a report to summarize the results, but for performance reasons I only want to call the function once per id 我有一个函数对传递的ID执行CPU大量计算,我正在处理报告以汇总结果,但是出于性能原因,我只希望每个ID调用一次函数

Here is a simple example of the working SQL BUT it calls the function once for each column. 这是一个有效的SQL BUT的简单示例,它为每一列调用一次函数。 How can I rewrite the query to only call the function once per identifier? 如何重写查询,以便每个标识符仅调用一次函数?

    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

You can just put the logic in a subquery before doing the sum, then reference the single column. 您可以在进行求和之前将逻辑放在子查询中,然后引用单列。

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;

A better solution in terms of performance though would be to look at what your scalar function actually does, and ask yourself does it need to be a function, can you make the solution set based? 在性能方面,更好的解决方案是查看标量函数的实际作用,并问自己是否需要成为函数,是否可以将解决方案集作为基础?

Instead of FROM employee , use a derived table that is defined like this: 代替FROM employee ,使用定义如下的派生表:

SELECT *, myfunction(employee_id) AS myFuncResult
FROM employee

Now, you have myFuncResult as an additional column. 现在,您将myFuncResult作为附加列。 Let's hope the optimizer does not mess with this strategy. 让我们希望优化器不会干扰该策略。 It does not have a good understanding of scalar function cost (in fact, none). 它对标量函数成本没有很好的了解(实际上没有)。

Since you are using SQL Server you could try the CROSS APPLY expression, just replace .Result with the name of the column that your function returns: 由于您使用的是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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM