MySQL中,如何分析你的 SQL 慢在哪里
前言
MySQL 是我们日常开发中最常用的关系型数据库之一,当随着数据库中的数据量增多,同样的SQL查询性能却开始下降,造成页面卡顿,数据加载缓慢。那么,如何分析出哪条SQL性能下降,就成了开发人员的必备技能。
查询分析工具
在MySQL中,数据库查询优化主要关注以下几个核心点:
- 哪条 SQL 慢?
- 慢在哪里?全表扫描?索引没命中?
- 哪些表最占 CPU 或 I/O?
- 是不是有锁竞争?
- 有没有重复查询、低效 Join?
本篇文章就带从工具和方法两个角度,去探究 MySQL 的查询分析问题排查。
1. EXPLAIN(SQL 预估执行计划)
EXPLAIN 是 MySQL 中最基础的分析命令,可以用来查看 SQL 查询时的执行计划,我们可以在将要查询的SQL语句前面加上 EXPLAIN,例如:
代码语言:sql复制 explain select * from tags where userId = 3;
执行结果如下:
因为tags表没有添加索引,所以从 type = ALL 可以判断出是全表扫描,性能很差。除此之外,常见的字段解释如下:
字段 | 含义 |
---|---|
id | 查询的标识号,表示查询中执行顺序 |
select_type | 查询类型(SIMPLE、PRIMARY、SUBQUERY) |
table | 当前执行的表 |
type | 联接类型,越靠近 ALL 性能越差 |
key | 实际使用的索引 |
rows | 扫描的行数,越少越好 |
2. SHOW PROFILE(SQL 执行时间分布)
SHOW PROFILE 命令用于分析 SQL 各阶段的耗时(解析、优化、执行等),执行之前需要先开启 profiling:
代码语言:sql复制SET profiling = 1;
-- 执行 SQL
select * from tags where userId = 3;
-- 查看耗时
SHOW PROFILES;
-- 查看详情
SHOW PROFILE FOR QUERY 1;
执行结果如下:
SHOW PROFILE 可以看出 SQL 总耗时,也可以查看 SQL 每个阶段用了多少时间,可以直观看出到底 CPU 的问题,还是 IO 卡住了。
3. 慢查询日志(Slow Query Log)
这是生产环境比较常用的诊断方式。开启慢查询日志后,MySQL 会自动把执行时间超过阈值的 SQL 记录下来。
在 /etc/myf 中添加配置:
代码语言:txt复制[mysqld]
# 开启慢查询日志功能
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
# 单位秒,超过1秒才记录
long_query_time = 1
然后重启 MySQL 服务,在 MySQL 中,可以查看慢日志是否开启;
我们可以执行几个慢sql语句,这里的阈值是1s,
这些慢事情了就被记录在了 slow.log 中。而我们可以通过 mysqldumpslow、pt-query-digest 等工具分析慢日志.
4. pt-query-digest
pt-query-digest 是由 Percona 提供专门用来分析慢查询日志的工具,首先执行下面命令安装 pt-query-digest。
代码语言:bash复制yum install .noarch.rpm
percona-release enable tools release
yum -y install percona-toolkit
安装成功之后,执行下面命令分析 slow.log 文件:
代码语言:bash复制pt-query-digest /var/log/mysql/slow.log
就会输出 SQL 分析结果,例如哪些 SQL 最慢、SQL 的执行次数、平均时间、哪些字段没有走索引等。
结语
要想提高查询效率,除了 SQL 本身之外,还可以合理地对条件字段添加索引,但太多索引会导致插入更新慢、占用空间大。同时也要慎用 JOIN 和子查询。