MySQL 调优笔记

1.如何定位慢查询?

定位慢查询主要依靠 MySQL 的慢查询日志配合工具如 pt-query-digest ,mysqldumpslow 进行分析,或者通过 performance_schema 进行实时监控,进一步可以使用 EXPLAIN 分析执行计划。

-> 开启慢查询日志

复制代码
-- 查看慢查询日志是否开启:
SHOW VARIABLES LIKE 'slow_query_log%';
-- 开启慢查询日志(立即生效)
SET GLOBAL slow_query_log = 'ON';
-- 设置慢查询时间阈值为 1 秒:
SET GLOBAL long_query_time = 1;
-- 设置慢查询日志文件路径(可选)
SET GLOBAL slow_query_log_file = '/var/log/mysql/mysql-slow.log';
-- 查看慢查询文件位置:
SHOW VARIABLES LIKE 'slow_query_log_file';
-- 查看慢查询总数:
SHOW GLOBAL STATUS LIKE 'Slow_queries';

-> 收集慢查询日志(慢于 long_query_time 的语句)

-> 使用工具提取 Top N 慢 SQL(如 pt-query-digest)

复制代码
mysqldumpslow -s t -t 10 /var/log/mysql/slow.log
pt-query-digest /var/log/mysql/slow.log

-> 对具体 SQL 使用 EXPLAIN 或 EXPLAIN ANALYZE 分析执行计划

复制代码
EXPLAIN SELECT * FROM user WHERE name LIKE '%abc%';
EXPLAIN ANALYZE SELECT * FROM user WHERE id = 123;

-> 判断是否索引失效 / 全表扫描 / 关联顺序不佳等

-> 优化 SQL 或加索引,重复测试

2.一个 SQL 语句执行很慢,如何分析 ?

我用 EXPLAIN 分析 SQL 时,重点关注以下几个字段:

type 是访问类型,性能最好的是 const(主键查单条)、eq_ref/ref(使用索引查找),次一点的是 range(范围扫描),最差的是 ALL(全表扫描),index(全索引扫描);

key 表示实际使用的索引,若为 NULL 则说明没有用到索引,通常性能较差,如果 possible_key 有值,而 key 为 null,证明有索引可能能用但是没命中,就需要考虑是什么原因导致了索引失效;

rows 代表预估扫描的行数,数字越小越好,过大说明扫描量大,效率低;

Extra 字段里如果出现 Using filesort 或 Using temporary,说明使用了额外的排序或临时表,通常是性能瓶颈;如果看到 Using index 则说明是覆盖索引,性能很好,避免了回表;

综上,通过这些字段可以判断 SQL 是否命中索引,扫描量是否合理,以及是否存在额外开销,从而指导优化方案。

3.什么情况下索引会失效 ?

1.违反最左前缀匹配原则: 复合索引(多列索引)只有从最左边的列开始按顺序使用,跳过最左列会失效。

2.使用了函数: 如 WHERE YEAR(create_time) = 2023,索引失效,因为函数包裹了列,MySQL 无法用索引直接匹配。

  1. 使用了通配符 % 开头的 LIKE:LIKE '%abc' 无法使用索引,因为前缀不确定,但 LIKE 'abc%' 是可以走索引的。

  2. 隐式类型转换: 查询条件的数据类型与索引列类型不匹配,会导致索引失效。

  3. OR 条件没有覆盖所有列的索引:如果只用部分索引,另一部分条件需要全表扫描,这样部分索引的使用反而可能加重了整体扫描成本。

  4. 使用了 NOT 或 <> 等否定条件: 例如 WHERE col <> 1,MySQL一般无法利用索引。

  5. 不等式比较符号(<, >, !=)后面的列索引不能用: 在复合索引中,使用不等式后,后续的列索引无法使用。 复合索引中,遇到范围查询(如 b > 10)后,索引只能定位该范围,后续列(如 c)索引失效,需回表过滤;而对同一列的多范围条件(如 b > 10 AND b < 20)则仍能利用索引缩小扫描范围。

4.MYSQL 超大分页怎么处理 ?

超大分页避免使用 LIMIT offset, size,改用基于唯一索引的范围查询(如 WHERE id > last_id LIMIT size)实现延迟关联,极大提升查询效率。或者分表分库通过拆分数据减少单表数据量。亦或者热点数据可考虑缓存。

5.谈谈你对 SQL 的优化的经验

  1. 合理设计索引

根据查询条件设计覆盖索引,尽量减少回表。

避免冗余和过多索引,减少写入负担。

注意复合索引最左前缀原则,尽量让查询条件匹配索引顺序。

  1. 优化查询语句

避免 SELECT *,只查需要的列。

避免在索引列上使用函数或表达式,保证索引可用。

拆分复杂查询,避免过多 JOIN 或子查询。

OR 语句可拆成多条 UNION 查询。

  1. 合理使用分页

避免大偏移量分页,使用基于唯一索引的延迟关联分页。

热点数据可考虑缓存。

  1. 分析执行计划

使用 EXPLAIN 分析查询路径,重点看 typepossible_keyskeyrowsExtra 字段。

确认索引是否被使用,避免全表扫描。

注意是否有 Using filesortUsing temporary,这可能是性能瓶颈。

5.数据量与分区

对超大表考虑分区或分表,降低单表压力。

归档历史数据,减少热点数据量。

相关推荐
TL滕2 分钟前
从0开始学算法——第二十一天(复杂链表问题)
笔记·学习·算法
tgethe4 分钟前
MySQL 进阶攻略
数据库·mysql
老王熬夜敲代码4 分钟前
IP和MAC的深入理解
linux·网络·笔记·网络协议
亮子AI6 分钟前
【node.js MySQL】node.js 如何连接 MySQL?
数据库·mysql·node.js
YJlio16 分钟前
FindLinks 学习笔记(12.4):NTFS 硬链接扫描与文件“多重身份”排查
笔记·学习·intellij-idea
Albert Edison23 分钟前
【MySQL】用户管理
mysql·adb
QT 小鲜肉25 分钟前
【Linux命令大全】001.文件管理之diff命令(实操篇)
linux·运维·chrome·笔记
Ahtacca27 分钟前
保姆级教程:Obsidian + PicGo + Gitee 搭建免费稳定的自动化图床
运维·笔记·学习·gitee·自动化
苦 涩29 分钟前
考研408笔记之计算机组成原理(二)——数据的表示和运算
笔记·计算机组成原理·考研408
ZHang......1 小时前
synchronized(三)
开发语言·笔记·juc