MySQL 升级后查询性能跳水,排序竟成“罪魁祸首”?
1.背景及分析
近期,罪魁祸首某客户完成对数据库 MySQL 5.7 到 8.0 的后竟成版本升级,升级后查询性能显著变慢。查询
原来是跳水 MySQL 8.0 对某些 ORDER BY 相关的参数修改,导致了优化器不生效。排序下面我们进入本次的罪魁祸首 SQL 优化分析,也建议升级后有类似情况的后竟成读者自检。
分析过程
首先,查询查看慢日志及对应的跳水表结构。
慢 SQL:select * from xx where xx order by xx limit xx.执行计划:发现 order by 的排序字段没有索引,若加上索引可从原来的罪魁祸首 4 秒变为毫秒级别。在升级前(MySQL 5.7),后竟成该字段没有索引,查询查询只需 1 秒左右,跳水需要找到这个原因。排序
通过执行计划(profile,trace 等方式)对比了升级前后的区别,发现只有 profile 会有明显的区别。其中,MySQL 5.7 的耗时主要在 Creating sort index 阶段,而 MySQL 8.0 的耗时都是在执行阶段。免费源码下载
在 MySQL 8.0 中 SELECT 少数字段时间也在 1 秒左右。随着 SELECT 查询的字段增多,时间也越来越长。当 select * 时能达到 4 秒,而 MySQL 5.7 中不管多少字段都是 1 秒左右。
根据以上信息可以推测,变慢主要在排序环节,需要进一步了解 MySQL 8.0 的排序方式发生了哪些改变。
通过 MySQL 官网文档[1] 可知:
MySQL 8.0.20 之前的版本:排序跟 max_length_for_sort_data 参数有关。当需要排序的行的大小大于参数设置对应的值时(byte),会使用 row_id 排序,反之使用全字段排序。通过测试,在 MySQL 5.7 版本时,设置参数的值若大于所有列对应的大小,select * 查询也需要耗时 4 秒左右。MySQL 8.0.20 及之后的版本:max_length_for_sort_data 参数被废弃,不再生效。
官网中对该参数的调整说明
分析完毕,下面我们将进行验证。
2.验证测试
在本次升级涉及的具体版本是源码下载 MySQL 5.7.44 和 MySQL 8.0.30。根据上面的分析过程,推断 MySQL 5.7.44 版在涉及到排序查询时会受到 max_length_for_sort_data 的影响,而 MySQL 8.0.30 则不会。
数据准备
在 MySQL 5.7 和 8.0 版本库中建表并插入 400W 行数据。
复制CREATE TABLE `t` ( `id` int NOT NULL AUTO_INCREMENT, `create_date` datetime DEFAULT NULL, `status` int DEFAULT NULL, `col1` varchar(50) DEFAULT NULL, `col2` varchar(50) DEFAULT NULL, `col3` varchar(50) DEFAULT NULL, `col4` varchar(50) DEFAULT NULL, `col5` varchar(50) DEFAULT NULL, `col6` varchar(50) DEFAULT NULL, `col7` varchar(50) DEFAULT NULL, `col8` varchar(50) DEFAULT NULL, `col9` varchar(50) DEFAULT NULL, `col10` varchar(50) DEFAULT NULL, `col11` varchar(255) DEFAULT NULL, `col12` varchar(255) DEFAULT NULL, `col13` varchar(255) DEFAULT NULL, `col14` varchar(255) DEFAULT NULL, `col15` varchar(255) DEFAULT NULL, `col16` varchar(255) DEFAULT NULL, `col17` varchar(255) DEFAULT NULL, `col18` varchar(255) DEFAULT NULL, `col19` varchar(255) DEFAULT NULL, `col20` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB; -- 插入数据过程略 select count(*) from `t`; +-------------+ | count( * ) | +-------------+ | 4194304 | +-------------+ 1 row in set (0.11 sec)1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.在 MySQL 5.7 和 8.0 版本环境中执行(参数配置一致),分别执行查询三个字段和查询所有字段两种 SELECT 语句。
复制-- 查询三个字段 select id,create_date,status from t where status=1 order by create_date desc limit 1; -- 查询所有字段 select * from t where status=1 order by create_date desc limit 1;1.2.3.4.5.MySQL 5.7的两种 SELECT 语句执行时间均为 1 秒左右。
MySQL 5.7 两种查询对比
MySQL 8.0查询三个字段 1 秒左右,查询所有字段则为 4 秒左右。
MySQL 8.0 两种查询对比
在 MySQL 8.0.30 查询的字段越多,时间越长。
对比查询 7 个字段和 11 个字段
若在 MySQL 5.7.44 中,把 max_length_for_sort_data 参数的值设置大于所有列的大小时,查询时间也会变慢(全字段排序)。

3.结论及优化方案
MySQL 8.0.20 及之后的版本,针对无索引的排序方式发现改变。不会再通过 max_length_for_sort_data 参数来判断,而是通过查询的字段和排序的字段大小动态来进行排序。所以在查询列较多时会导致比 MySQL 5.7 更慢。
最好的解决方式是源码库给排序字段加上索引 :)
参考资料
[1]order-by-optimization: https://dev.mysql.com/doc/refman/8.0/en/order-by-optimization.html
作者:龚唐杰,爱可生 DBA 团队成员,主要负责 MySQL 技术支持,擅长 MySQL、PG、国产数据库。
相关文章
解决电脑显示360错误的有效方法(快速修复电脑显示360错误,让您的电脑正常运行)
摘要:电脑作为现代生活中不可或缺的一部分,经常会遇到各种问题,其中显示360错误是一个常见的困扰。这些错误可能导致电脑运行缓慢、程序无法正常启动或运行等问题。本文将介绍一些有效的方法来修...2025-11-04因特尔显卡的性能与特点(探索因特尔显卡的革新技术和出色性能)
摘要:在当今高度数字化的时代,显卡作为电脑中重要的核心组件之一,对于游戏、多媒体和图形处理等任务的执行起着至关重要的作用。因特尔作为全球知名的芯片制造商,其显卡产品凭借卓越的技术和优秀的...2025-11-04- 摘要:作为现代科技的重要组成部分,投影幕在影音领域发挥着重要的作用。而以美视投影幕为主题的文章将会为大家详细介绍这款产品的特点和优势,带领读者进入一个震撼的视听世界。1.逼真...2025-11-04
戴森加湿器的性能及用户评价(舒适湿度体验,戴森加湿器是如何满足你的需求的)
摘要:戴森加湿器作为一款优质的家居电器产品,以其出色的性能和用户评价备受关注。本文将从多个角度详细介绍戴森加湿器的特点和用户评价,为大家提供全面的了解。科技领先,戴森加湿器采用空...2025-11-04惠普暗影精灵6新手教程(掌握惠普暗影精灵6,打造专业级游戏体验)
摘要:惠普暗影精灵6是一款专为游戏玩家设计的高性能笔记本电脑,它拥有卓越的处理能力、出色的图形性能和出色的散热系统,适合各种类型的游戏。本篇文章将为大家提供惠普暗影精灵6的新手入门指南,...2025-11-04- 摘要:现代人喜欢养宠物,而小狗是最受欢迎的宠物之一。然而,随之而来的问题是,小狗身上常常寄生着讨厌的螨虫,给我们和小狗带来很多困扰。为了解决这一问题,科学家们研发出了小狗除螨仪。本文将详...2025-11-04

最新评论