首页 > 解决方案 > Oracle 是否会在引用聚合/分析函数时重新计算它们?

问题描述

不是针对任何特定情况,只是关于 SQL 软件(例如 Oracle)如何实现聚合/分析功能以帮助我编写更有效的代码的问题。

基本上,我很好奇 Oracle 是否在缓存计算的聚合/分析函数值方面做得很聪明,如果它们被多次引用。例如,采取以下两个查询:

-- Query A
select 
    PRODUCT, 
    sum(SALES) as TOTSALES,                 -- (1)
    log(sum(SALES)+1,10) as LOG_TOTSALES    -- (2)
from EXAMPLE_TABLE
group by PRODUCT
order by sum(SALES);                        -- (3)

-- Query B
select 
    PRODUCT, 
    TOTSALES,
    log(TOTSALES+1,10) as LOG_TOTSALES
from (
    select PRODUCT, sum(SALES) as TOTSALES
    from EXAMPLE_TABLE
    group by PRODUCT
) 
order by TOTSALES;

完成同样的事情。查询 A 的简单实现将评估sum(SALES)三次(两次在 select 中,一次在 order by 中)。查询 B 仅在内部查询中对其进行一次评估,然后按显式 NUM 列计算/排序。

所以问题是 Oracle/MySQL/etc 是否在引擎盖下对 Query A 这样的情况做任何聪明的事情。我可以想象这样一种情况,当编译器遇到第一个时sum(SALES),它会保存一个新的标识符。然后当它看到log(sum(SALES)+1,10)(它没有标识符)并尝试解析它时,识别sum(SALES)已经计算的并查找缓存的值。

如果在选择中调用相同的分析函数 > 1 次,则同样可以工作,例如

select 
   DATE,
   SALES as TODAY_SALES,
   lag(SALES,1) over (order by DATE) as YEST_SALES,
   SALES - (lag(SALES,1) over (order by DATE)) as DIFF_SALES
from DAILY_SALES;

如果lag(SALES,1)第一次缓存,则不需要计算两次。但我不知道这是否会在实现中造成其他麻烦,在这种情况下,我应该编写像查询 B 这样的代码以提高效率。

谢谢!

编辑:替换count(*)sum(SALES)更具说明性的示例。

标签: sqlaggregateanalytic-functions

解决方案


推荐阅读