0

0

mysql中优化执行流程中IO与CPU消耗的平衡

P粉602998670

P粉602998670

发布时间:2026-03-01 12:26:42

|

697人浏览过

|

来源于php中文网

原创

explain 的 type=all 不一定触发磁盘 io,取决于数据是否在 buffer pool 中;buffer pool hit rate 低于 99% 表明缓存压力大,需结合 handler_read_rnd_next 与 innodb_data_reads 分析读性能瓶颈。

mysql中优化执行流程中io与cpu消耗的平衡

为什么 EXPLAIN 显示 type=ALL 却不一定是全表扫描?

MySQL 的 type=ALL 表示“全表扫描”,但实际是否触发大量磁盘 IO,取决于数据是否已在 InnoDB Buffer Pool 中。如果表小、访问频繁,ALL 可能只走内存页,CPU 消耗高(遍历行、判断 WHERE),IO 几乎为零;反之,若 Buffer Pool 不足、数据冷,就会引发大量 read() + lseek() 系统调用,IO 成瓶颈。

实操建议:

  • SHOW ENGINE INNODB STATUS\G 查看 Buffer pool hit rate,低于 99% 就说明缓存压力大
  • 对比 Handler_read_rnd_next(随机读行数)和 Innodb_data_reads(物理读次数),比值远大于 1 表示大量逻辑读未命中缓存
  • 避免在 WHERE 中对索引列做函数操作(如 WHERE YEAR(created_at) = 2024),否则即使有索引也退化为 ALL

什么时候该加 Covering Index 而不是普通索引?

Covering Index 能同时解决 IO 和 CPU 争用:它让查询只通过 B+ 树叶子节点完成(无需回表),既减少磁盘随机读(IO↓),又省去聚簇索引二次查找和行解析开销(CPU↓)。但代价是索引体积变大、写入变慢。

适用场景:

  • 查询字段固定且数量少(如 SELECT id, status, updated_at FROM orders WHERE user_id = ?
  • WHERE 条件字段 + SELECT 字段合起来不超过 16KB(InnoDB 单页上限),否则可能触发页分裂
  • 表写入频率不高,或业务可接受 INSERT/UPDATE 延迟增加 5–10%

建索引示例:

ALTER TABLE orders ADD INDEX idx_user_cover (user_id, status, updated_at, id);

注意:字段顺序必须满足最左前缀原则,且 id 放最后——因为 user_id 是过滤条件,其余是覆盖字段。

innodb_buffer_pool_size 设多大才不浪费内存又不拖慢查询?

这个参数不是越大越好。设太大(如占物理内存 90%)会导致 OS 缺页、swap 频繁,反而放大 IO 延迟;设太小(如

hstshop鸿思特商城系统
hstshop鸿思特商城系统

鸿思特商城系统HstShop是一款B2C独立网店系统,由拥有十年互联网开发经验的牛头带队开发完成,完全免费开源,适合大中型网站平台快速构建立强大的网上商城平台网店系统。HstShop悉心听取每一位商家的需求与建议,根据中国人的购物习惯改进了购物流程,实现更好的用户购物体验。HstShop网店系统无论在产品功能、稳定性、执行效率、负载能力、安全性和搜索引擎优化等方面都居国内同类产品领先地位,成为国内

下载

推荐计算方式:

  • 查当前活跃数据量:SELECT FLOOR(SUM(data_length + index_length) / 1024 / 1024) AS mb FROM information_schema.tables WHERE table_schema = 'your_db';
  • 再乘以 1.2–1.5 倍(留出 MVCC 版本、自适应哈希等开销)
  • 上限不要超过物理内存的 75%,且确保 OS 至少保留 2GB 给文件系统缓存和后台进程

动态调整命令(无需重启):

SET GLOBAL innodb_buffer_pool_size = 4294967296; -- 4GB

调整后观察 Innodb_buffer_pool_wait_free 是否持续 > 0,若是,说明分配过快导致内部碎片,需分批调大(每次 512MB)。

为什么加了索引,ORDER BY 还会触发 Using filesort

MySQL 只有在索引顺序与 ORDER BY 完全一致、且 WHERE 条件能利用该索引最左前缀时,才能避免 filesort。一旦出现类型转换、NULL 值比较、或 ORDER BY 字段不在索引中,优化器就放弃索引排序能力。

典型陷阱:

  • WHERE status IN ('paid','shipped') ORDER BY created_at DESC → 若索引是 (status),不包含 created_at,必触发 filesort
  • ORDER BY created_at DESC NULLS LAST → MySQL 8.0.13+ 才支持 NULLS LAST 语义,旧版本直接忽略,仍按默认规则排,可能无法复用索引
  • JOINORDER BY 用的是被驱动表字段 → 优化器通常无法下推排序,只能归并后排序

验证方法:执行 EXPLAIN FORMAT=tree,看输出里是否有 "using_filesort": true 字段。

真正难平衡的从来不是配置数值,而是理解每一行 Handler_read_* 计数背后,到底是磁盘在转,还是 CPU 在空转。多数人调参只盯着 innodb_buffer_pool_size,却漏看了 innodb_random_read_ahead 在 SSD 上反而拖慢随机点查——硬件特性变了,老经验就得重验。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

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

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

682

2023.06.20

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

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

452

2023.06.21

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

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

286

2023.07.18

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

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

519

2023.07.19

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

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

264

2023.07.25

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

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

392

2023.08.08

sqlserver和mysql区别
sqlserver和mysql区别

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

541

2023.08.11

mysql忘记密码
mysql忘记密码

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

662

2023.08.14

Golang 测试体系与代码质量保障:工程级可靠性建设
Golang 测试体系与代码质量保障:工程级可靠性建设

Go语言测试体系与代码质量保障聚焦于构建工程级可靠性系统。本专题深入解析Go的测试工具链(如go test)、单元测试、集成测试及端到端测试实践,结合代码覆盖率分析、静态代码扫描(如go vet)和动态分析工具,建立全链路质量监控机制。通过自动化测试框架、持续集成(CI)流水线配置及代码审查规范,实现测试用例管理、缺陷追踪与质量门禁控制,确保代码健壮性与可维护性,为高可靠性工程系统提供质量保障。

24

2026.02.28

热门下载

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

精品课程

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

共48课时 | 2.4万人学习

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

共3课时 | 0.3万人学习

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

共1课时 | 842人学习

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

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