性能监控工具是任何时候都需要的,能及时发现问题。
MySQL 慢查询日志
performance_schema
sys schema
常见的优化场景
- 大表关联查询优化
- 分页查询优化
- 子查询优化
- 大批量数据操作优化
数据库连接数不够?
- 增加数据库最大连接数:修改数据库配置文件,增加 max_connections 参数
的值。
– 修改 MySQL 最大连接数 SET GLOBAL max_connections = 1000;
- 使用连接池技术:使用连接池可以复用数据库连接,减少连接创建和销毁的开 销。
- 优化应用代码:减少数据库连接占用时间,例如使用批量操作、异步操作等。
数据库 IO 或者 CPU 比较高?
– 查看 MySQL 当前正在执行的 SQL 语句
- SHOW PROCESSLIST;
– 查看 MySQL 状态信息- SHOW STATUS LIKE ‘Threads_connected’;
- SHOW STATUS LIKE ‘Innodb_buffer_pool_reads’;
数据库参数优化示例
需要根据实际硬件等情况,结合Mysql官网文档和最佳实践、压测等,设置合理的参数值
– 修改 MySQL InnoDB 缓冲池大小
2 SET GLOBAL innodb_buffer_pool_size = 1G;
事务比较长?
尽量缩短事务执行时间: 例如,将耗时的操作移到事务外执行。
• 将大事务拆分为多个小事务: 例如,将批量插入操作拆分为多个小批量插入操 作。
• 避免在事务中进行耗时操作: 例如,避免在事务中进行网络请求、文件操作等。
完整回答示例
我采用系统化的五步法进行 SQL 调优,确保全面覆盖所有优化可能性:
1、问题诊断与基准测试
- 捕获问题 SQL:通过慢查询日志或监控系统
- 建立性能基线:记录当前执行时间、资源消耗
- 使用 EXPLAIN 分析:重点关注 type 列和Extra
一、type
列性能等级
类型 | 扫描方式 | 触发场景及优化建议 | 索引使用情况 |
---|---|---|---|
ALL |
全表扫描 | 未使用索引,需检查WHERE条件或添加合适索引 | 无索引 |
index |
全索引扫描 | 遍历整个索引树,通常需优化为范围扫描 | 使用索引但效率低 |
range |
索引范围扫描 | 使用BETWEEN 、> 等范围条件,需注意索引选择性 |
有效利用索引 |
ref |
非唯一索引等值匹配 | 使用普通索引或联合索引前缀列查询 | 单值匹配 |
eq_ref |
唯一索引等值匹配 | 多表JOIN时主键/唯一索引关联,性能最佳 | 主键或唯一索引 |
const |
常量条件查询 | 通过主键/唯一索引直接定位单行 | 最高效的索引访问 |
注:从
ALL
到const
效率逐步提升,理想情况下应达到ref
及以上级别。
二、Extra
列关键信息解析
常见值 | 含义及优化建议 |
---|---|
Using filesort |
需要额外排序操作,建议添加索引避免临时排序 |
Using temporary |
使用临时表,常见于GROUP BY/ORDER BY未用索引,需优化查询结构 |
Using index |
覆盖索引(仅通过索引获取数据),性能最佳 |
Using where |
存储引擎检索数据后需服务器层再过滤,检查索引是否未完全覆盖条件 |
Using join buffer |
多表关联时使用连接缓冲,可适当调大join_buffer_size 参数 |
Impossible WHERE |
WHERE条件永远为假,需检查业务逻辑 |
- 监控实时指标:CPU、IOPS、锁等待、临时表等
2、执行计划分析与优化
- 索引优化:
- 检查是否走错索引:force index 测试不同索引效果
- 避免索引失效、创建复合索引(最左前缀原则)、覆盖索引优化:避免回表操作
- 查询重写:
- 拆分复杂查询:将大查询拆分为多个小查询
- 优化关联顺序:小表驱动大表
- 子查询优化:转写为 JOIN
- 只查询必要字段
3、数据库配置调优
- 关键参数调整:
- 缓冲池大小(innodb_buffer_pool_size)
- 排序缓冲区(sort_buffer_size)
- 连接线程数(thread_pool_size)
4、架构级优化
- 读写分离、分库分表、缓存策略、数据归档
5、验证与监控
- A/B 测试:对比优化前后性能
- 执行计划对比:确认优化效果
- 建立监控:持续跟踪 SQL 性能
- 压测验证:模拟高峰场景