Oracle 11g中HAVING子句多聚合函数写法的性能差异咨询
Oracle 11g 两条SQL查询性能差异解答
核心结论
两条查询不存在性能差异,HAVING 子句中多次调用相同聚合函数不会产生额外性能损耗。
Oracle 11g 优化器处理逻辑
Oracle 11g 查询优化器自带**公共子表达式消除(Common Subexpression Elimination)**优化能力,对于同一条SQL中多次出现的、参数完全一致的聚合函数调用,优化器只会在GROUP BY分组阶段计算一次,后续所有引用该聚合结果的位置都会直接复用缓存的计算值,不会重复执行聚合运算。
你提到的两种写法本身就是完全等价的:
- 写法1的
BETWEEN -0.009 AND 0.009语法,在Oracle的语法解析阶段就会被自动改写为sum(t.amount) >= -0.009 AND sum(t.amount) <= 0.009的判断逻辑,和写法2的语义完全一致 - 写法2中两次出现的
sum(t.amount)属于完全相同的公共子表达式,优化器会自动识别,不会重复计算
执行计划验证方式
你可以自行执行执行计划查询对比,会发现两条SQL的执行计划完全一致,执行成本没有任何区别:
- 由于
t.id字段存在索引,优化器会优先选择索引全扫描/索引快速全扫描读取数据,避免回表产生额外IO - 分组阶段会利用索引的有序性直接完成分组聚合,仅计算一次
sum(t.amount) - 最终对聚合结果做过滤,两种写法的过滤逻辑消耗完全相同
执行计划查询代码
-- 查看查询1的执行计划 EXPLAIN PLAN FOR select t.id, sum(t.amount) from transaction t group by t.id having sum(t.amount) between -0.009 and 0.009; SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY()); -- 查看查询2的执行计划 EXPLAIN PLAN FOR select t.id, sum(t.amount) from transaction t group by t.id having sum(t.amount) >= -0.009 and sum(t.amount)<= 0.009; SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());
内容的提问来源于stack exchange,提问作者SCCJS
相关产品推荐
相关产品推荐

