GaussDB(for MySQL)剪枝功能,让“多表连接+DISTINCT”查询性能提升70倍!

💡 原文中文,约2000字,阅读约需5分钟。
📝

内容提要

华为云数据库内核工程师介绍了通过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关键词用于返回唯一不同的值,常用于数据去重。它可以用于单列数据去重,也可以做多列去重,即只有所有指定列的信息都相同时,才会被认为是重复的信息。

🏷️

标签

➡️

继续阅读