如何针对MySQL 5.7的高并发写入场景优化索引带来的IO压力?

陌萱姑娘_3474

陌萱姑娘_3474

2026-08-07

378人浏览

原创

结论:高并发写入下索引导致insert卡在updating状态,本质是每条insert需同步更新多个b+树且强制fsync redo,引发io瓶颈;优化应优先删无用索引、控制刷盘频率与并发量。

如何针对mysql 5.7的高并发写入场景优化索引带来的io压力?

直接说结论:高并发写入下索引带来的IO压力,本质是“每条INSERT要同步更新多个B+树 + 强制fsync redo”,不是索引本身慢,而是它把IO瓶颈一次性点爆了。优化方向必须是“减索引、控刷盘、压并发”,而不是硬扛。

为什么加索引会让INSERT变卡在updating状态?

你看到的连接卡在 updating 状态,背后是两个机制同时生效:

  • InnoDB 必须为每条新记录同步更新所有二级索引,B+树插入 + 页分裂开销随索引数量非线性增长
  • innodb_flush_log_at_trx_commit=1(默认)强制每次 COMMIT 都 fsync redo 日志,建索引期间DML密集,IO瓶颈被彻底暴露

尤其当表已有5个以上二级索引时,单条写入的IO放大效应会非常明显——这不是参数能“调”出来的,是结构决定的。

删掉不用的索引比调大innodb_log_file_size更有效

很多人一上来就改日志文件大小或buffer pool,但真正容易被忽略的是:大量索引根本没人用。MySQL 5.7没内置 sys.schema_unused_indexes(那是8.0+才有的),得靠自己查:

SELECT object_schema, object_name, index_name
FROM performance_schema.table_io_waits_summary_by_index_usage
WHERE index_name IS NOT NULL
  AND count_star = 0
ORDER BY object_schema, object_name;

执行前确保已开启相关instrument:UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME LIKE 'wait/io/table%';

常见误建索引场景:

MySQL
MySQL

编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。

下载
  • 只在 WHERE 中用 status,却建了 (status, created_at, id) 联合索引,但实际查询从不带 created_at
  • 对 JSON 字段建了普通索引,但应用层始终用 JSON_EXTRACT 解析后过滤
  • 冗余唯一索引:主键已是唯一,又对同一字段加 UNIQUE

写多读少的表,优先用普通索引而非唯一索引

高并发写入时,唯一索引会强制做唯一性校验,可能触发额外的change buffer合并或直接读页——尤其当二级索引页不在buffer pool中时,随机IO陡增。

实操建议:

  • 如果业务层已保证唯一性(比如发号器生成ID),就别在数据库层再加 UNIQUE 约束
  • 对写入热点字段(如 user_id、order_status)建索引,优先选普通索引;唯一性由应用兜底
  • 避免在写入频繁的字段上建函数索引(如 INDEX idx_upper_name ((UPPER(name)))),MySQL 5.7不支持函数索引,实际是无效的

innodb_flush_log_at_trx_commit设为2时,必须同步调大innodb_log_buffer_size

设为2能明显缓解IO压力,但有个关键前提:log buffer要够大,否则仍会频繁刷盘。默认 innodb_log_buffer_size=1M 在高并发写入下极易成为瓶颈。

调整建议:

  • 先观察 SHOW GLOBAL STATUS LIKE 'Innodb_log_waits';,值 > 0 就说明buffer太小
  • 按写入强度估算:若平均每事务写入2KB日志、QPS为1000,则buffer至少需 2KB × 1000 = 2MB,建议起步设为 4M
  • 同时增大 innodb_log_file_size 到 1G(需停机操作),否则checkpoint太频繁,反而抵消buffer收益

注意:innodb_flush_log_at_trx_commit=2 意味着崩溃可能丢失1秒内事务,仅适用于可接受该风险的场景。

真正卡点从来不在“加索引”动作本身,而在它把原本就存在的IO争抢、锁等待、日志空间不足全暴露出来。先砍掉无用索引,再控住写入节奏,最后才动参数——顺序错了,调一天也白忙。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

mysql mysql优化 mysql索引

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
mysql修改数据表名
mysql修改数据表名

MySQL修改数据表:1、首先查看数据库中所有的表,代码为:‘SHOW TABLES;’;2、修改表名,代码为:‘ALTER TABLE 旧表名 RENAME [TO] 新表名;’。php中文网还提供MySQL的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.20

2173

6

MySQL创建存储过程
MySQL创建存储过程

存储程序可以分为存储过程和函数,MySQL中创建存储过程和函数使用的语句分别为CREATE PROCEDURE和CREATE FUNCTION。使用CALL语句调用存储过程智能用输出变量返回值。函数可以从语句外调用(通过引用函数名),也能返回标量值。存储过程也可以调用其他存储过程。php中文网还提供MySQL创建存储过程的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.21

1319

5

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

775

5

mysql密码忘了怎么查看
mysql密码忘了怎么查看

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql密码忘了怎么办呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.19

2952

5

mysql创建数据库
mysql创建数据库

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql怎么创建数据库呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.25

4948

4

mysql默认事务隔离级别
mysql默认事务隔离级别

MySQL是一种广泛使用的关系型数据库管理系统,它支持事务处理。事务是一组数据库操作,它们作为一个逻辑单元被一起执行。为了保证事务的一致性和隔离性,MySQL提供了不同的事务隔离级别。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.08

1119

3

sqlserver和mysql区别
sqlserver和mysql区别

SQL Server和MySQL是两种广泛使用的关系型数据库管理系统。它们具有相似的功能和用途,但在某些方面存在一些显著的区别。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.11

5211

4

mysql忘记密码
mysql忘记密码

MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。那么忘记mysql密码我们该怎么解决呢?php中文网给大家带来了相关的教程以及其他关于mysql的文章,欢迎大家前来学习阅读。

2023.08.14

4602

7

mysql事务隔离级别
mysql事务隔离级别

mysql规范中定义了四种事务隔离级别,不同的隔离级别对事务的处理有所不同。本专题为大家提供mysql事务隔离级别相关的文章内容,大家可以免费体验。

2023.08.16

6054

11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 183人学习