本篇属于高级SQL优化专题中的一篇,高级SQL优化系列专题介绍PawSQL优化引擎以及Oracle等数据库查询优化算法原理及优化案例,欢迎大家订阅。
本文所使用的执行计划可视化工具为 PawSQL Explain Visualizer , 支持MySQL、PostgreSQL、openGauss、Oracle等数据库。
HAVING条件下推是指将符合条件的HAVING子句中的过滤谓词下推至同一个查询块中的WHERE子句,从而提升查询效率的重写优化算法。
从逻辑上,HAVING条件是在分组之后执行的,而WHERE子句上的条件可以在表访问的时候(索引访问),或是表访问之后、分组之前执行,这两种都比方式都在分组之前进行了过滤操作,降低了分组的数据集大小,所以执行代价要小。
考虑下面的例子,
select o_custkey, count(*) from orders group by o_custkey having o_custkey < 100重写后的SQL为,
select o_custkey, count(*) from orders where o_custkey < 100 group by o_custkeyAND连接的条件从执行计划可以看到,HAVING子句的条件o_custkey < 100是在分组聚集运算后进行运算的,导致分组前无法进行过滤,所以分组运算处理36042行,执行时间达237.49ms。

通过将HAVING子句的条件o_custkey < 100下推至WHERE子句,使得后续的分组聚集运算行数大大减少;同时可以利用在o_custkey列上的索引,整体的执行时间也降低到1.36ms.

通过将HAVING子句的条件o_custkey < 100下推至WHERE子句,提前过滤,使得后续的分组运算的行数大大减少(36042 vs. 2742);同时可以利用在o_custkey列上的索引进行覆盖索引顺序扫描,整体的执行时间从237.49ms降低到1.36ms,性能提升了170多倍。


我们可以看到,MySQL、PostgreSQL、Oracle数据库的优化器都没有对HAVING条件下推重写优化的支持。



PawSQL专注数据库性能优化的自动化和智能化,支持MySQL,PostgreSQL,Opengauss等,提供的SQL优化产品包括