MySQL随机主键查询TPS瓶颈排查:CPU未达满负载原因分析
随机主键查询场景下MySQL的TPS瓶颈分析
先直接给结论:从你给出的测试数据和硬件环境来看,当前场景下MySQL的TPS瓶颈是磁盘随机IO,而CPU使用率无法拉满的核心原因,正是磁盘IO的瓶颈限制了CPU的利用率。
一、为什么判断瓶颈是磁盘随机IO?
你的查询是SELECT * FROM address WHERE id=?,虽然id是主键,但因为是随机取值,每次查询都需要从磁盘上随机定位对应的InnoDB页(InnoDB的主键是聚簇索引,数据和索引存储在一起)。机械硬盘的随机IO性能天生很差,每秒只能处理几百到上千次随机IO,当线程数增加到30时,所有线程都在排队等待磁盘IO完成,根本没法继续推进任务,自然TPS和CPU使用率都停滞不前。
从你的测试数据也能看出端倪:线程数从10涨到20时,TPS从14000升到18000,但CPU使用率只从15%涨到23%——这说明新增的线程大多在等待IO,没给CPU增加多少实际工作。到30线程时完全停滞,这完全符合磁盘IO饱和的表现。
二、逐一排除其他可能的原因
咱们挨个拆解你提到的几个因素:
- 网络延迟:ping只有0.4ms,100M带宽的容量远没被用满(单条查询的数据包极小,18000TPS的总带宽消耗连1M都不到),所以网络绝对不是限制因素。
- 线程调度:12核CPU跑30线程,调度开销根本不会大到让CPU跑不满,要是真的是调度问题,CPU的系统态占比会很高,但你的CPU整体才用了23%,显然不是。
- MySQL本身:InnoDB处理主键查询的逻辑非常简单,没有复杂计算,单条查询的CPU消耗极低,所以MySQL自身的处理能力完全没到瓶颈。
- 磁盘IO:这才是核心——机械硬盘的随机IO能力顶不住了,大量线程处于IO等待状态(你可以用
show engine innodb status查看Pending normal aio reads指标,肯定会看到很高的数值),CPU没足够的任务可执行,使用率自然上不去。
三、验证方法和优化建议
- 验证瓶颈:用
iostat工具查看磁盘的%util指标,如果这个数值接近100%,就实锤磁盘IO已经饱和了。 - 优化方向:
- 换成SSD硬盘:SSD的随机IO性能是机械硬盘的几十到上百倍,能直接把这种随机查询的TPS拉上去。
- 调大InnoDB缓冲池:服务器有8GB内存,你可以把
innodb_buffer_pool_size设为6GB左右,让更多热点数据缓存到内存里,减少磁盘IO的次数。 - 批量查询(如果业务允许):把多个随机id的查询合并成一条
SELECT * FROM address WHERE id IN (?, ?, ...),减少单次IO的开销。
内容的提问来源于stack exchange,提问作者lxc
相关产品推荐
相关产品推荐

