GaussDB(for MySQL)剪枝功能,让“多表连接+DISTINCT”查询性能提升70倍!
内容提要
华为云数据库内核工程师介绍了通过MySQL提升多表连接下DISTINCT查询效率的方法。GaussDB(for MySQL)通过剪枝功能减少扫描工作量,大幅提升查询效率,执行耗时和扫描数据量减少近70倍。
延伸解读
剪枝优化的核心机制
GaussDB(for MySQL)的剪枝优化基于火山模型执行器,当找到满足DISTINCT条件的值后,通过全局变量判断是否可以提前结束本轮迭代,并层层退出,从而减少不必要的扫描。这种动态剪枝机制针对多表连接+DISTINCT场景,能有效裁剪无用数据,提升查询效率。
启用剪枝特性的步骤
用户可以通过设置特性开关来启用剪枝优化:执行SET rds_nlj_distinct_optimize=ON;。之后,使用EXPLAIN FORMAT=TREE查看执行计划,如果出现“join with distinct optimization”关键字,说明特性已生效,查询过程中可进行减枝优化。
性能提升的实测数据
在典型测试中,对7个表连接后的结果做DISTINCT,MySQL 8.0社区版执行耗时186秒,扫描约4400万行数据;而GaussDB(for MySQL)仅需2.7秒,扫描约61万行,执行耗时和扫描数据量减少近70倍,显著提升了查询效率。
Q&A
GaussDB(for MySQL)的剪枝功能是什么?
GaussDB(for MySQL)的剪枝功能是在执行优化器中加入的一种优化技术,用于去除不必要的扫描分支,节省查询耗时。它特别适用于多表连接+DISTINCT场景,通过提前减枝优化,当找到满足条件的DISTINCT值后,通过全局变量判断是否可以提前结束本轮迭代,并层层退出,大幅减少扫描工作量。
为什么MySQL 8.0在多表连接下执行DISTINCT查询效率低?
MySQL 8.0在多表连接下执行DISTINCT时,需要扫描表连接后的结果。当表连接数量多或基表数据量大时,扫描的数据量也会很大,导致执行效率很低。例如,对7个表连接后的结果做DISTINCT,MySQL 8.0.30社区版本执行耗时186秒,扫描了约4400万行数据。
GaussDB(for MySQL)剪枝功能如何提升多表连接+DISTINCT查询性能?
GaussDB(for MySQL)在火山模型的执行器上实现了提前减枝优化。当找到满足条件的DISTINCT值之后,通过全局变量判断是否可以提前结束本轮迭代,并层层退出,大幅减少了扫描工作量。例如,在示例中,只需扫描28行数据就可获得最终结果集,相比MySQL 8.0社区版本扫描60行,性能显著提升。
如何启用GaussDB(for MySQL)的剪枝优化?
可以通过设置特性开关来启用剪枝优化:SET rds_nlj_distinct_optimize=ON; 然后通过”EXPLAIN FORMAT=TREE”查看特性是否生效,执行计划中出现” join with distinct optimization”关键字说明特性生效。
GaussDB(for MySQL)剪枝功能在典型场景下的性能提升效果如何?
在典型场景测试中,GaussDB(for MySQL)执行耗时2.7秒完成,只需要扫描数据量约61万行;相比MySQL 8.0社区版本执行耗时约186秒,扫描数据量4400万,执行耗时和扫描数据量减少近70倍,实现了执行效率飞跃式提升。
DISTINCT关键词在SQL中有什么作用?
DISTINCT关键词用于返回唯一不同的值,常用于数据去重。它可以用于单列数据去重,也可以做多列去重,即只有所有指定列的信息都相同时,才会被认为是重复的信息。