0

0

SQL IO 成为瓶颈时如何处理?

冷漠man

冷漠man

发布时间:2026-01-23 19:47:02

|

757人浏览过

|

来源于php中文网

原创

确认磁盘IO是瓶颈需满足:MySQL iowait持续>10%且iostat显示某盘%util≥95%、await>10ms(SSD应<1ms);缓冲池命中率<95%、Innodb_data_reads突增、iotop显示mysqld刷写、INNODB STATUS有大量pending reads、Created_tmp_disk_tables持续上涨。

sql io 成为瓶颈时如何处理?

怎么确认磁盘 IO 真是瓶颈?

别一慢就猜 IO,得用数据说话。最直接的信号是:MySQL 进程的 iowait 持续高于 10%,同时系统级 iostat -x 1 显示某块盘 %util 长期 ≥95%、await 超过 10ms(SSD 应该在 1ms 内)。这时再查 MySQL 内部指标:Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests 算出的缓冲池命中率若低于 95%,说明大量请求被迫落盘;Innodb_data_reads 每秒突增几千甚至上万,基本坐实物理读爆炸。

  • iotop -o 能立刻看到是不是 mysqld 在刷写,而不是备份或日志轮转抢了 IO
  • SHOW ENGINE INNODB STATUS\G 里 “FILE I/O” 段若出现大量 pending reads,代表后台线程已跟不上请求节奏
  • Created_tmp_disk_tables 持续上涨,说明排序/分组被迫写磁盘,不是内存能扛住的

哪些 SQL 最容易把磁盘 IO 打爆?

不是慢查询才危险,而是“扫得多、写得勤、临时多”的语句——它们不一定会超 long_query_time,但每秒都在制造随机 IO。

  • 全表扫描(EXPLAINtype=ALL)且 rows > 10 万:哪怕只执行一次,也可能触发数 GB 物理读
  • ORDER BY + LIMIT 深度分页(如 LIMIT 100000,20):MySQL 得先扫完前 10 万行再取 20 行,中间全走磁盘
  • GROUP BYDISTINCT 大结果集:内存不够时自动写 /tmp,IO 峰值常被忽略
  • 批量 INSERT/UPDATE 未分批:一次塞 10 万行,会密集刷 redo log 和脏页,IO 曲线像心电图

开启 log_queries_not_using_indexes = ON,比只依赖慢日志更能揪出这类“不慢但很脏”的语句。

配置和硬件上怎么快速止损?

优化 SQL 是治本,但业务压过来时得先稳住 IO。优先动这几项:

  • innodb_buffer_pool_size 设为物理内存的 70%~80%:不够大,热数据留不住,等于天天重读磁盘
  • innodb_flush_log_at_trx_commit 从 1 改成 2:单机可靠性可接受时,能砍掉约 70% 的 redo log 同步 IO(注意:崩溃可能丢 1 秒事务)
  • redo log 文件(ib_logfile*)和 binlog 单独放到 SSD 分区,别和数据文件挤在一起
  • 检查 innodb_log_file_size:太小(如默认 48MB)会导致频繁 checkpoint,产生大量脏页刷盘;建议总和设为 1~2GB(需停库调整)

机械硬盘还没换 SSD?至少把 undo tablespacetemp tablespace 移到更快的盘上——它们是 IO 黑洞高发区。

抖云猫AI论文助手
抖云猫AI论文助手

一款AI论文写作工具,最快 2 分钟,生成 3.5 万字论文。论文可插入表格、代码、公式、图表,依托自研学术抖云猫大模型,生成论文具备严谨的学术专业性。

下载

为什么加了索引,IO 还没降下来?

索引不是万能解药。常见失效场景:

  • 查询条件用了函数:WHERE DATE(create_time) = '2026-01-01' → 索引失效,必须改成 create_time BETWEEN '2026-01-01' AND '2026-01-01 23:59:59'
  • 复合索引顺序错:INDEX(a,b) 支持 WHERE a=1 AND b=2,但不支持 WHERE b=2 单独查询
  • 返回字段太多:SELECT * 导致回表次数暴增,尤其当 text/blob 字段存在时,每次回表都可能触发额外 IO
  • 统计信息过期:ANALYZE TABLE 没跑过,优化器误判走索引比全表扫描还贵,干脆放弃

EXPLAIN FORMAT=JSONused_columnskey_length,比光看 key 字段更准。

真正卡住的地方,往往不在最显眼的慢查询里,而在那些每秒执行几百次、每次扫几万行、又没进慢日志的“温吞水”SQL——它们安静地把 IO 吞噬殆尽。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

685

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

323

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

348

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

1117

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

359

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

717

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

577

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

419

2024.04.29

C++ 高级模板编程与元编程
C++ 高级模板编程与元编程

本专题深入讲解 C++ 中的高级模板编程与元编程技术,涵盖模板特化、SFINAE、模板递归、类型萃取、编译时常量与计算、C++17 的折叠表达式与变长模板参数等。通过多个实际示例,帮助开发者掌握 如何利用 C++ 模板机制编写高效、可扩展的通用代码,并提升代码的灵活性与性能。

10

2026.01.23

热门下载

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

精品课程

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

共48课时 | 1.9万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 805人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号