首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >MySQL8.4运维实录:3个案例带你吃透MySQL并行查询,大表扫描不再头大

MySQL8.4运维实录:3个案例带你吃透MySQL并行查询,大表扫描不再头大

作者头像
俊才
发布2026-01-27 14:48:31
发布2026-01-27 14:48:31
1270
举报
文章被收录于专栏:数据库干货铺数据库干货铺

本文首发于「数据库干货铺」公众号,转载请联系授权

做MySQL运维久了就懂,参数调优从来不是对着官方文档改数字那么简单——很多参数看着好用,一到生产环境就踩坑,要么没效果,要么反而拖垮业务。

innodb_parallel_read_threads就是这么个“看似简单、实则有门道”的参数。MySQL8.4把它的默认值改成了自适应,但在不同业务场景、不同硬件配置下,默认值往往不够用。这篇就结合我亲手处理过的3个真实案例,跟大家唠唠这个参数的实操玩法,全是踩坑后的干货,看完直接能套到自己的业务里。

先说明下,这3个案例都基于MySQL8.4 LTS版本,覆盖了电商、日志分析、政务系统三大常见场景,服务器从2核云主机到64核物理机都有,参考性应该够强。

在讲案例前,先给大家画个简单的原理图,搞懂这个参数的核心逻辑——为啥多线程能提速?本质是“任务分片”:

简单说,单线程是“一个人干所有活”,并行是“多个人分工干”,这就是提速的核心。下面结合案例,看这种分工在不同场景下的实际效果。

一、 案例1:电商4200万+行用户表,count(*)从18秒砍到2.3秒

先说个最常见的场景——报表统计的count(*)慢查询。之前接手过一个电商客户,他们核心用户表user_info存了4200万+行数据,18GB大小,字段都是常规的用户信息,没大字段。服务器是32核64GB内存配SSD,MySQL8.4.5版本,按官方自适应规则,innodb_parallel_read_threads默认是4(32核/8)。

问题很典型:每天凌晨3点,报表系统要跑一次select count(*) from user_info统计总用户数,给运营做日报。这语句一跑就是18到20秒,更烦的是,跑的时候会压IO,导致同期的订单同步任务偶尔超时告警。

我查了慢查询日志,rows_examined确实是4200万+,Extra里也显示Using index,说明已经命中主键聚簇索引了,没走全表扫描。但top命令一看,CPU利用率才3%到5%——32核的机器,就一个线程在干活,资源全浪费了。

运维调优最怕瞎改全局参数,所以我先在会话级测试,避免影响业务:

代码语言:javascript
复制
-- 先试8个线程,比默认多一倍
set  innodb_parallel_read_threads=8;
select count(*) from user_info; -- 跑出来8.7秒,快了一半多
-- 再试16个线程,接近32核的一半
set   innodb_parallel_read_threads=16;
select count(*) from user_info; -- 2.3秒!效果拉满
-- 贪心试了下32个线程,想把核数拉满
set   innodb_parallel_read_threads=32;
select count(*) from user_info; -- 2.5秒,反而慢了点

后来才想明白,线程数不是越多越好,超过16之后,线程切换的开销就盖过并行收益了。确定16是最优值后,我改了my.cnf,也用SET PERSIST让参数立即生效(MySQL8.*的新特性,不用重启数据库,这点太香了)。

优化后效果很明显:耗时从18.2秒压到2.3秒,CPU利用率升到25%到30%,刚好在安全阈值内,订单同步任务再也没报过错。这里提醒下,千万不要追求CPU拉满,留足余量给业务线程才是稳妥的。

二、 案例2:1.8亿行日志表在线DDL,从“卡壳”到18分钟搞定

这个案例是日志分析平台的,坑点在在线DDL。客户的app_log表存了1.8亿行日志,200GB大小,服务器是64核128GB内存配NVMe SSD,MySQL8.4.5。

需求是给这张表加个二级索引idx_create_time(create_time),用于按时间范围查日志。重点要求是在线DDL,不能锁表,毕竟日志表24小时都在写入。

第一次执行alter table语句(algorithm=inplace, lock=none),跑了60分钟才完成50%,进度条一动不动。监控一看,IO util直接干到95%,但CPU利用率才8%——又是单线程扫描聚簇索引拖了后腿。后来翻官方文档才确认,在线DDL建二级索引时,聚簇索引的扫描速度就靠这个参数控制,而索引排序、构建是由innodb_ddl_threads管的(默认4个就够)。

给大家补一张在线DDL的流程拆解图,清楚看到这个参数的作用范围:

能看出来,A阶段是超大表DDL的核心瓶颈,把这一步的并行线程调对,整体效率就能大幅提升。这次我直接把会话级线程数调到32(64核的一半),再跑DDL:

代码语言:javascript
复制
set  innodb_parallel_read_threads=32;
alter table app_log add index idx_create_time(create_time), algorithm=inplace, lock=none;

跑的时候盯着processlist和监控,聚簇索引扫描阶段的CPU利用率直接冲到40%,IO util稳定在70%,进度条匀速推进。最终整个DDL只花了18分钟,其中聚簇索引扫描才用了8分钟,比之前卡壳的情况好太多,业务也没受任何影响。

这里踩了个小坑:一开始我以为调大这个参数就能让整个DDL变快,后来发现它只管聚簇索引扫描阶段,后面的排序和索引构建阶段,调这个参数没用,得配合innodb_ddl_threads。不过大部分超大表DDL的瓶颈都在扫描阶段,把这个参数调好,效率就能翻倍。

三、案例3:政务系统CHECK TABLE,45分钟缩到5分钟

政务系统的案例比较特殊,核心是数据一致性和窗口时间。客户的tb1表存了8000万行民生数据,80GB大小,服务器是16核32GB内存配SAS硬盘(不是SSD,IO性能偏弱),MySQL8.4.2版本。按公式16核/8=2,低于参数最小值4,所以默认是4。

他们每周日凌晨要跑一次CHECK TABLE tb1,检查数据页完整性,毕竟是民生数据,一点差错都不能有。但默认参数下,这命令要跑45分钟,而且跑的时候会加共享锁——虽然不影响读写,但会阻塞后续的索引优化任务,周日的维护窗口本来就短,根本耗不起。

查看了下CHECK TABLE的执行流程,发现第二阶段的索引完整性校验是耗时大头,而这个阶段刚好支持并行扫描,还是由innodb_parallel_read_threads控制。既然是维护窗口执行,我就大胆试了不同线程数:

代码语言:javascript
复制
-- 默认4个线程,基准耗时45分钟
set innodb_parallel_read_threads=4;
check table business_data; 
-- 调到8个线程,快了不少
set innodb_parallel_read_threads=8;
check table business_data; -- 12分钟
-- 再往上调到12个线程,接近16核的上限
set innodb_parallel_read_threads=12;
check table business_data; -- 5分钟搞定!

这里有个意外发现:SAS机械硬盘场景下,并行扫描的优化效果比SSD更明显。因为机械硬盘IO延迟高,多线程能有效掩盖延迟,把IO利用率拉起来。最终我把全局参数调到8(兼顾日常count(*)和常规查询),每周日跑CHECK TABLE时,临时在会话级调到12,既不影响日常业务,又能大幅缩短维护窗口。

四、 总结

innodb_parallel_read_threads不算什么高深的参数,但它胜在“零代码修改”——不用改业务SQL,不用做分表分库,只要调对数值,就能在特定场景下实现数倍提速,这对运维来说太实用了。这3个案例跑下来,我也总结了几个实操准则,都是血和泪的经验。

  • 场景别用错,不然白忙活

这个参数对三类场景有效:无WHERE的count(*)、CHECK TABLE第二阶段、在线DDL建二级索引时的聚簇索引扫描。带WHERE条件的查询、JOIN关联这些,调了也没用,别瞎折腾。

  • 线程数有阈值,别贪多(我的实践结果,大家可以参考,不一定准确)
  • 百万级小表:保持MySQL8.4默认值就行,调大了反而增加线程切换开销,感受不到效果
  • 千万级中表:按逻辑核数的一半调,上限16,超过后收益会回落
  • 亿级大表:逻辑核数的一半到三分之二,上限64,再高就没必要了
  • 避坑3个关键点
  • 高峰期别乱调:并行扫描会占CPU和IO,高峰期调大线程数,容易和业务抢资源,导致业务延迟;
  • 特殊索引会退化:表有虚拟列、全文索引、空间索引时,并行扫描会自动切成单线程,调参数也没用,先检查索引类型;
  • 不用担心缓冲池污染:并行扫描的页面会放在缓冲池LRU尾部,用完就被淘汰,不会占着宝贵的缓存空间。

其实运维调优的核心,就是摸清参数的适用场景,结合自己的硬件和业务,一点点测试迭代,而不是照搬官方文档或别人的配置。毕竟每个系统的情况都不一样,别人的最优解,可能就是你的坑。

你们在生产环境里调整参数时,有没有遇到过奇怪的问题?比如调整后性能反而下降?欢迎留言聊一聊,互相避坑~

关注微信公众号「数据库干货铺」,获取更多数据库运维干货。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-01-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据库干货铺 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档