You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

MySQL 8.0与5.7 Group by性能差异原因咨询

MySQL 8.0 Group By性能大幅超越5.7的核心原因解析

根据你给出的对比测试细节,MySQL 8.0在Group By查询上实现的10倍性能提升,核心源于优化器对索引利用逻辑、临时表引擎以及排序机制的针对性改进。结合你的测试场景,具体原因可以拆解为以下几点:

1. 覆盖索引下的Group By排序优化

你的查询语句是:

select count(0),pad from sbtest2 where k between 400000 and 600000 group by pad limit 1

表上存在idx1 (k,pad)联合覆盖索引,这是关键前提:

  • 在MySQL 5.7中,虽然优化器能识别到覆盖索引,但Group By需要对pad字段做排序来分组,因此会触发Using filesort;当内存临时表容纳不下数据时,还会转成磁盘临时表(MyISAM引擎),这两个步骤带来了巨大的IO和CPU开销,也是你看到耗时21.88秒的核心原因。
  • MySQL 8.0优化了覆盖索引与Group By的协同逻辑:当联合索引的后缀字段恰好是Group By的目标字段时,优化器可以直接利用索引的有序性来构建临时表,完全避免了额外的排序操作(也就是explainUsing filesort消失的原因),从根源上消除了排序带来的性能损耗。

2. 临时表引擎的全面升级

临时表是Group By查询的核心组件,8.0在这方面做了质的提升:

  • MySQL 5.7默认使用MEMORY引擎作为内存临时表,它对字符类型的支持有限,且当数据量超过tmp_table_size时会自动转成MyISAM磁盘临时表,MyISAM的磁盘IO效率极低。
  • MySQL 8.0引入了TempTable存储引擎作为默认临时表:它支持所有数据类型,能动态调整内存分配,当内存不足时会切换到InnoDB磁盘临时表(复用InnoDB缓冲池缓存,IO效率远高于MyISAM)。这就是你在8.0的show profile中看不到磁盘临时表相关步骤的原因,彻底规避了磁盘IO的性能瓶颈。

3. 优化器成本模型的精准调整

MySQL 8.0重构了优化器的成本计算逻辑,对于Group By这类需要临时表和排序的场景,优化器能更准确地评估不同执行计划的成本,优先选择“覆盖索引+内存临时表”的高效路径;而5.7的优化器在类似场景下,可能会因为成本评估偏差,选择效率较低的执行方式。

结合你的测试结果验证:

  • 5.7的explain输出Using where; Using index; Using temporary; Using filesort,对应排序+磁盘临时表的高开销;
  • 8.0的explain仅显示Using where; Using index; Using temporary,无排序和磁盘IO开销,直接将耗时压缩到2.32秒,完全匹配上述优化点的效果。

内容的提问来源于stack exchange,提问作者user1819769

火山引擎 最新活动