MySQL慢查询定位

MySQL慢查询定位

引言

网站访问缓慢很多根源是执行时间过长的SQL。开启MySQL慢查询日志,可以捕获执行超时SQL,找到需要优化的语句,是数据库性能排查的核心手段。

慢查询基础配置

慢查询日志会记录执行时长超过指定阈值的SQL语句。

-- 查看慢查询是否开启
SHOW VARIABLES LIKE 'slow_query_log';

-- 设置阈值,单位秒,超过1秒就记录
SET GLOBAL long_query_time =1;

常用分析工具

  1. mysqldumpslow:mysql自带工具,统计慢日志
    mysqldumpslow -s t /var/lib/mysql/slow.log
  2. pt-query-digest:percona工具,分析效果更强,适合大量日志。

优化排查流程

  1. 开启慢查询,收集慢SQL;
  2. 使用explain查看执行计划,判断是否缺少索引;
  3. 优化where条件,添加合适索引,改写SQL逻辑;
  4. 优化完成后,持续观察慢日志确认效果。

示例

EXPLAIN SELECT * FROM article WHERE title like '%PHP%';

看type字段,ALL代表全表扫描,是需要优化的信号。

总结

慢查询日志用来抓取低效SQL,但是开启会少量增加服务器IO压力,生产环境可以按需开启。定位到慢SQL后优先检查索引,再调整SQL写法,解决数据库卡顿问题。


emer 发布于  2026-10-18 07:15 

MySQL慢查询排查,explain分析SQL执行计划

前言

网站突然变慢,数据库CPU100%?多半是慢查询搞的鬼。本文讲怎么开启慢查询日志、用explain分析SQL执行计划,找到慢的原因。

一、开启慢查询日志

临时开启

-- 查看慢查询是否开启
SHOW VARIABLES LIKE 'slow_query_log';

-- 开启慢查询
SET GLOBAL slow_query_log = ON;

-- 超过1秒就算慢查询
SET GLOBAL long_query_time = 1;

永久开启

编辑my.cnf:

vi /etc/my.cnf

加:

slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1

重启MySQL:

systemctl restart mysqld

看慢查询日志

tail -f /var/log/mysql/slow.log

二、explain是什么

explain用来分析SQL是怎么执行的,看有没有用索引、扫了多少行。

用法

EXPLAIN SELECT * FROM users WHERE name = '张三';

三、explain字段解释

id

SELECT的标识符,越大越先执行。

select_type

查询类型:

  • SIMPLE:简单查询
  • PRIMARY:主查询
  • SUBQUERY:子查询

table

查的哪张表。

type(最重要)

访问类型,从好到差:

类型 含义
system 表只有一行
const 主键或唯一索引匹配,只查一行
eq_ref 主键或唯一索引匹配
ref 普通索引匹配
range 索引范围查询(between、>、<)
index 扫整个索引树
ALL 全表扫描(最坏!)

重点看: 出现ALL就是全表扫描,要加索引。

possible_keys

可能用到的索引。

key

实际用到的索引。

key是NULL就是没用到索引。

rows

预估要扫描多少行。

越大越慢。

Extra

额外信息:

值 含义
Using where 服务器在存储引擎返回后再过滤
Using index 用了覆盖索引,不错
Using temporary 用了临时表,不好
Using filesort 用了文件排序,不好

四、常见慢查询原因

原因1:没加索引

SELECT * FROM users WHERE name = '张三';

name字段没索引 → 全表扫描 → 慢。

解决: 加索引

ALTER TABLE users ADD INDEX idx_name(name);

原因2:索引失效

虽然加了索引,但SQL写法不对,索引用不上。

索引失效的情况:

  1. 对索引字段用函数:

    SELECT * FROM users WHERE LEFT(name, 3) = '张三'; -- 索引失效
  2. 索引字段用运算:

    SELECT * FROM users WHERE age + 1 = 20; -- 索引失效
  3. 最左前缀原则不满足:

    -- 联合索引(a, b, c)
    SELECT * FROM t WHERE b = 1; -- 索引失效
  4. like以%开头:

    SELECT * FROM users WHERE name LIKE '%张三%'; -- 索引失效
  5. 类型不匹配:

    -- phone是varchar
    SELECT * FROM users WHERE phone = 13800138000; -- 索引失效

原因3:SELECT *

查了不需要的字段,占内存。

解决: 只查需要的字段

SELECT id, name FROM users WHERE ...

原因4:大表分页越查越慢

SELECT * FROM users ORDER BY id LIMIT 100000, 10;

慢的原因: 要先扫10万行再跳过。

解决:

SELECT u.* FROM users u
INNER JOIN (SELECT id FROM users ORDER BY id LIMIT 100000, 10) t
ON u.id = t.id;

五、实战案例

慢SQL

SELECT * FROM orders WHERE user_id = 123 AND status = 1 ORDER BY create_time DESC LIMIT 10;

explain分析

EXPLAIN SELECT * FROM orders WHERE user_id = 123 AND status = 1 ORDER BY create_time DESC LIMIT 10;

发现: type是ALL,key是NULL → 全表扫描。

加索引

ALTER TABLE orders ADD INDEX idx_user_status_time(user_id, status, create_time);

再explain: type变成ref,key是idx_user_status_time → 用上索引了。

六、优化原则

  1. WHERE条件加索引
  2. ORDER BY字段加索引
  3. 联合索引遵守最左前缀
  4. **不要SELECT ***
  5. 避免在索引字段上用函数
  6. 大分页用子查询优化

七、常见坑

坑1:加了索引但没用

原因: SQL写法导致索引失效。

排查: explain看key字段。

坑2:索引加太多

索引不是越多越好,写的时候要维护索引,会变慢。

建议: 单表索引不超过5个。

坑3:区分度低的字段不加索引

比如gender(男/女),加索引没用。

原则: 区分度高的字段加索引。

总结

记住:

  1. 开启慢查询日志找慢SQL
  2. 用explain分析SQL执行计划
  3. type=ALL就是全表扫描,要加索引
  4. key=NULL就是没用到索引
  5. rows越大越慢
  6. 索引失效要避免

最常用:

EXPLAIN SELECT * FROM users WHERE ...

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-9 07:49 

MySQL查看慢查询日志,long_query_time参数

前言

网站突然变慢,不知道哪条SQL拖后腿。开慢查询日志,把跑得慢的SQL都抓出来优化。

一、什么是慢查询日志

慢查询日志(slow query log)记录执行时间超过阈值的SQL语句。

作用: 找到慢SQL,优化它们。

二、查看是否开启

SHOW VARIABLES LIKE 'slow_query_log';
Variable_name Value
slow_query_log OFF

OFF就是没开。

三、开启慢查询日志

方法1:临时开启(重启失效)

-- 开启
SET GLOBAL slow_query_log = ON;

-- 设置阈值(超过2秒算慢)
SET GLOBAL long_query_time = 2;

方法2:永久开启

改my.cnf:

[mysqld]
# 开启慢查询
slow_query_log = 1

# 慢查询阈值(秒)
long_query_time = 2

# 慢查询日志文件位置
slow_query_log_file = /var/log/mysql/slow.log

# 没走索引的SQL也记下来(可选)
log_queries_not_using_indexes = 1

重启MySQL:

systemctl restart mysqld

四、查看慢查询日志

直接看文件

tail -f /var/log/mysql/slow.log

用mysqldumpslow分析

MySQL自带的分析工具:

# 按查询时间排序,取前10
mysqldumpslow -s t -t 10 /var/log/mysql/slow.log

常用参数:

参数 说明
-s t 按时间排序
-s c 按次数排序
-s l 按锁时间排序
-t 10 取前10条
-g 过滤关键词

示例:

# 按次数最多的排
mysqldumpslow -s c -t 20 /var/log/mysql/slow.log

# 只看select语句
mysqldumpslow -g "select" /var/log/mysql/slow.log

五、用pt-query-digest分析

更专业的分析工具(需要安装):

pt-query-digest /var/log/mysql/slow.log

输出更详细的统计报告。

六、常用参数说明

参数 默认值 说明
slow_query_log OFF 是否开启
long_query_time 10 慢查询阈值(秒)
slow_query_log_file 主机名-slow.log 日志文件位置
log_queries_not_using_indexes OFF 没走索引的也记
log_output FILE 日志输出方式(FILE/TABLE)

七、优化慢SQL

找到慢SQL后怎么优化:

1. 加索引

EXPLAIN SELECT * FROM users WHERE name = '张三';

看type是不是ALL,是ALL说明没走索引。

2. 避免select *

只查需要的字段:

-- 别这样
SELECT * FROM users;

-- 这样
SELECT id, name FROM users;

3. 避免大表全表扫描

加where条件,加limit。

4. 优化分页

大表分页越查越慢,用游标分页。

常见坑

坑1:long_query_time设太小

设成0.1秒,日志文件爆炸,全是慢SQL。

建议: 生产环境设1-2秒。

坑2:日志文件越来越大

慢查询日志一直写,磁盘满了。

解决: 用logrotate切割日志。

坑3:开启慢查询影响性能

开慢查询本身有性能损耗。

解决: 排查完就关掉,或者用低采样率。

坑4:long_query_time不生效

改了参数,但还是记录所有SQL。

原因: 连接没断开,用的还是旧参数。

解决: 重新连接MySQL。

坑5:log_output=TABLE占满系统表

把慢查询写到mysql.slow_log表,表越来越大。

解决: 定期清理:

TRUNCATE TABLE mysql.slow_log;

总结

开启三步:

  1. SET GLOBAL slow_query_log = ON
  2. SET GLOBAL long_query_time = 2
  3. 看日志:mysqldumpslow -s t -t 10 slow.log

记住: 慢查询日志是优化数据库的第一步,先找到慢SQL再优化。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-8 07:55 

MySQL 慢查询优化实战

MySQL 慢查询优化实战

数据库慢查询是性能瓶颈的常见原因,学会优化很重要。

1. 开启慢查询日志

-- 查看是否开启
SHOW VARIABLES LIKE 'slow_query_log';

-- 开启慢查询
SET GLOBAL slow_query_log = ON;

-- 设置慢查询时间(秒)
SET GLOBAL long_query_time = 1;

2. 分析慢查询

用 EXPLAIN 分析:

EXPLAIN SELECT * FROM users WHERE name = '张三';

重点看:

  • type:访问类型,ALL 是全表扫描,要优化
  • key:用了哪个索引
  • rows:扫描行数

3. 常见优化方法

1)加索引:

-- 加索引
ALTER TABLE users ADD INDEX idx_name(name);

*2)避免 SELECT :**

-- 不好
SELECT * FROM users;

-- 好
SELECT id, name FROM users;

3)避免在索引字段上做运算:

-- 不好
SELECT * FROM users WHERE YEAR(create_time) = 2026;

-- 好
SELECT * FROM users WHERE create_time >= '2026-01-01' AND create_time < '2027-01-01';

4)避免 LIKE 左模糊:

-- 不好(用不到索引)
SELECT * FROM users WHERE name LIKE '%张%';

-- 好
SELECT * FROM users WHERE name LIKE '张%';

4. 分页优化

-- 不好(大偏移量慢)
SELECT * FROM users LIMIT 100000, 10;

-- 好(用子查询)
SELECT * FROM users WHERE id >= (
    SELECT id FROM users LIMIT 100000, 1
) LIMIT 10;

5. 常见慢查询原因

  • 没加索引
  • 索引失效
  • 关联查询太多
  • 数据量太大
  • 大表分页

总结

MySQL 慢查询优化要点:

  • 开启慢查询日志
  • 用 EXPLAIN 分析
  • 合理加索引
  • 避免全表扫描
  • 优化分页查询

数据库优化是个细活,多分析多测试。


emer 发布于  2026-10-8 07:19 

MySQL慢查询开启,定位慢SQL语句方法

前言

网站越来越慢,不知道哪条 SQL 拖后腿。MySQL 自带慢查询日志功能,能把执行慢的 SQL 记录下来,方便优化。

什么是慢查询

就是执行时间超过某个阈值的 SQL 语句。默认阈值是 10 秒,太久了,一般改成 1 秒或者 2 秒。

临时开启(重启不丢)

登录 MySQL:

mysql -u root -p

开启慢查询:

-- 开启慢查询
SET GLOBAL slow_query_log = ON;

-- 设置超过1秒就记录
SET GLOBAL long_query_time = 1;

-- 查看慢查询日志位置
SHOW VARIABLES LIKE 'slow_query_log_file';

永久开启(改配置文件)

改 my.cnf:

vi /etc/my.cnf

加上:

slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1

重启 MySQL:

systemctl restart mysqld

慢查询日志长什么样

# Time: 2026-10-07T07:00:00.000000Z
# User@Host: root[root] @ localhost []  Id:  1234
# Query_time: 5.234567  Lock_time: 0.000123 Rows_sent: 1000  Rows_examined: 1000000
SET timestamp=1728270000;
SELECT * FROM users WHERE name LIKE '%张%';

重点看:

  • Query_time:执行时间
  • Rows_examined:扫描了多少行
  • 最后一行就是慢 SQL 语句

分析慢查询日志

用 mysqldumpslow 工具:

# 找出最慢的10条SQL
mysqldumpslow -s t -t 10 /var/log/mysql/slow.log

# 找出返回数据最多的10条
mysqldumpslow -s r -t 10 /var/log/mysql/slow.log

参数说明:

参数 说明
-s t 按时间排序
-s r 按返回行数排序
-t 10 显示前10条

常见坑

坑1:没开启慢查询

不知道怎么开,或者开了忘了。

解决: 用 SHOW VARIABLES LIKE 'slow_query_log'; 确认一下。

坑2:阈值设太大

默认是 10 秒,10 秒以下的慢 SQL 都没记录到。

解决: 改成 1 秒,够用了。

坑3:日志太大占磁盘

慢查询日志一直写,磁盘满了。

解决: 配 logrotate 定期切割。

坑4:没记录没走索引的SQL

有些 SQL 虽然快,但没走索引,数据量一大就慢了。

解决: 加上这个参数,没走索引的也记录:

log_queries_not_using_indexes = 1

总结

三步开启慢查询:

  1. 开 slow_query_log
  2. 设 long_query_time
  3. 用 mysqldumpslow 分析

记住: 慢查询日志是优化数据库的第一步,先开了再说。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-7 07:53 

MySQL 性能优化实战

MySQL 性能优化实战

数据库慢是网站性能的大问题,这篇讲实战优化方法,从几个方面下手。

1. 慢查询排查

先找到慢SQL,再优化。

开启慢查询日志:

-- 查看是否开启
SHOW VARIABLES LIKE 'slow_query_log%';

-- 开启慢查询
SET GLOBAL slow_query_log = ON;

-- 设置慢查询阈值(秒)
SET GLOBAL long_query_time = 1;

用 explain 分析:

EXPLAIN SELECT * FROM users WHERE name = '张三';

重点看:

  • type:有没有用到索引(ref/const 好,ALL 全表扫描坏)
  • key:实际用的索引
  • rows:扫描行数

2. 索引优化

建索引原则:

  • where 条件经常用的字段建索引
  • 联合索引最左前缀原则
  • 避免建太多索引,影响写入

查看索引:

SHOW INDEX FROM users;

建索引:

-- 普通索引
CREATE INDEX idx_name ON users(name);

-- 联合索引
CREATE INDEX idx_name_age ON users(name, age);

-- 唯一索引
CREATE UNIQUE INDEX idx_email ON users(email);

3. SQL 优化

**不要 SELECT ***

-- 坏
SELECT * FROM users WHERE id = 1;

-- 好
SELECT id, name, email FROM users WHERE id = 1;

避免 LIKE 前导模糊:

-- 坏(用不到索引)
SELECT * FROM users WHERE name LIKE '%张%';

-- 好(能用索引)
SELECT * FROM users WHERE name LIKE '张%';

大表分页优化:

-- 坏(深度分页慢)
SELECT * FROM users LIMIT 100000, 10;

-- 好(子查询先定位)
SELECT * FROM users 
WHERE id >= (SELECT id FROM users LIMIT 100000, 1) 
LIMIT 10;

4. 表结构优化

  • 用合适的数据类型(能用 int 就别用 bigint)
  • 字段尽量 NOT NULL
  • 大表分表分库

5. 配置优化

my.cnf 常用配置:

# 缓冲池大小(内存的 70%)
innodb_buffer_pool_size = 1G

# 连接数
max_connections = 500

# 慢查询日志
slow_query_log = 1
long_query_time = 1

6. 总结

MySQL 优化三步走:

  1. 找慢SQL: 慢查询日志 + explain
  2. 加索引: where 条件字段
  3. 优化SQL: 不写 SELECT *,避免全表扫描

数据库优化不是一蹴而就,要持续监控和调整。


emer 发布于  2026-10-7 07:14 

MySQL慢查询开启,定位慢SQL语句方法

前言

做网站开发的同学肯定遇到过这种情况:网站打开越来越慢,数据库CPU占用很高,但就是不知道哪条SQL语句拖慢了整个系统。这时候就需要用到MySQL的慢查询日志功能,把执行慢的SQL语句记录下来,然后逐个优化。

这篇文章就详细讲讲如何开启MySQL慢查询日志,以及怎么用它来定位和优化慢SQL语句。

操作步骤

1. 先查看当前慢查询日志的状态

登录MySQL之后,先看看慢查询日志有没有开启:

SHOW VARIABLES LIKE '%slow_query_log%';

执行完之后会看到类似下面的输出:

+---------------------+-----------------------------------------------+
| Variable_name       | Value                                         |
+---------------------+-----------------------------------------------+
| slow_query_log      | OFF                                           |
| slow_query_log_file | /var/lib/mysql/izuf6w7x1x2x3x4x5x6x-slow.log  |
+---------------------+-----------------------------------------------+

从这里可以看到,slow_query_log 是 OFF 状态,说明慢查询日志没有开启。

2. 查看当前慢查询时间阈值

慢查询的默认时间阈值是10秒,也就是说执行时间超过10秒的SQL才会被记录。这个阈值对生产环境来说太大了,一般我们会改成1秒或者2秒。

查看当前阈值:

SHOW VARIABLES LIKE 'long_query_time';

3. 临时开启慢查询日志(重启后失效)

如果只是想临时排查问题,可以直接在MySQL命令行里开启,不需要重启服务:

-- 开启慢查询日志
SET GLOBAL slow_query_log = 'ON';

-- 设置慢查询阈值为1秒
SET GLOBAL long_query_time = 1;

这样设置之后,执行时间超过1秒的SQL语句就会被记录到慢查询日志文件里了。

4. 永久开启慢查询日志(修改配置文件)

临时开启的方式在MySQL重启之后就会失效,如果想长期开启,需要修改MySQL的配置文件。

找到MySQL的配置文件,一般是 /etc/my.cnf 或者 /etc/mysql/my.cnf,在 [mysqld] 下面添加以下配置:

[mysqld]
# 开启慢查询日志
slow_query_log = 1
# 慢查询日志文件位置
slow_query_log_file = /var/log/mysql/slow.log
# 慢查询阈值,单位秒
long_query_time = 1
# 没有用到索引的SQL也记录下来
log_queries_not_using_indexes = 1

修改完配置文件之后,重启MySQL服务:

systemctl restart mysqld

5. 查看慢查询日志内容

慢查询日志开启之后,执行慢的SQL语句就会被记录到日志文件里。我们可以直接查看日志文件:

cat /var/log/mysql/slow.log

不过慢查询日志的格式比较复杂,直接看日志文件不太直观。我们可以用 mysqldumpslow 工具来分析:

# 查看最慢的10条SQL
mysqldumpslow -s t -t 10 /var/log/mysql/slow.log

# 查看访问次数最多的10条SQL
mysqldumpslow -s c -t 10 /var/log/mysql/slow.log

6. 使用EXPLAIN分析慢SQL

找到慢SQL之后,下一步就是分析这条SQL为什么慢。我们可以用 EXPLAIN 关键字来查看SQL的执行计划:

EXPLAIN SELECT * FROM users WHERE name = '张三';

执行完之后会输出很多字段,我们重点关注这几个:

  • type:访问类型,最好是 const、eq_ref,最差是 ALL(全表扫描)
  • key:实际用到的索引,如果是 NULL 说明没用到索引
  • rows:扫描的行数,这个值越大越慢
  • Extra:额外信息,如果看到 Using filesort 或者 Using temporary 就说明需要优化了

常见坑

坑1:开启了慢查询但日志文件里什么都没有

很多同学开启了慢查询日志,但是去看日志文件却发现什么都没有。这通常是因为以下几个原因:

  1. 慢查询时间阈值设置得太大了,你的SQL执行时间还没超过阈值
  2. 日志文件的路径不对,你看的不是正确的日志文件
  3. MySQL没有权限写入日志文件,需要检查文件权限

坑2:long_query_time设置了但不生效

有时候你设置了 long_query_time = 1,但是发现执行时间0.5秒的SQL也被记录下来了。这是因为当前已经建立的MySQL连接还是用的旧的阈值,需要重新连接MySQL才能生效。

坑3:慢查询日志文件太大占满磁盘

如果你的网站访问量很大,慢查询日志可能会增长得非常快,几天就把磁盘占满了。所以一定要配置日志切割,或者定期清理慢查询日志文件。

总结

MySQL慢查询日志是定位数据库性能问题的必备工具,核心就三步:

  1. 开启慢查询日志,设置合理的时间阈值(一般1秒)
  2. 用mysqldumpslow工具分析慢查询日志,找到最慢的SQL
  3. 用EXPLAIN分析慢SQL的执行计划,针对性优化(加索引、改写SQL等)

掌握了慢查询日志的使用方法,网站数据库性能问题就能快速定位和解决了。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-5 08:23 

MySQL 慢查询优化技巧

MySQL 慢查询优化实战技巧

数据库慢查询是生产环境最常见的性能问题之一。掌握慢查询优化技巧,能让系统性能提升数倍。

1. 开启慢查询日志

先开启慢查询日志,找出哪些 SQL 慢:

slow_query_log = 1
long_query_time = 1
slow_query_log_file = /var/log/mysql/slow.log

超过1秒的查询就会被记录。

2. 用 Explain 分析

慢 SQL 拿到后,用 EXPLAIN 分析执行计划:

EXPLAIN SELECT * FROM users WHERE name = '张三';

重点看:

  • type:访问类型,ALL 是全表扫描,要优化
  • key:实际用到的索引
  • rows:扫描行数
  • Extra:额外信息,Using filesort、Using temporary 要警惕

3. 加索引

最直接的优化就是加索引:

ALTER TABLE users ADD INDEX idx_name(name);

加索引原则:

  • WHERE、JOIN、ORDER BY 字段优先
  • 区分度高的字段效果好
  • 联合索引遵循最左前缀

4. 避免 SELECT *

只查需要的字段:

-- 不好
SELECT * FROM users WHERE id = 1;

-- 好
SELECT id, name FROM users WHERE id = 1;

5. 深分页优化

LIMIT 100000, 10 很慢,因为要扫描10万行:

-- 不好
SELECT * FROM users LIMIT 100000, 10;

-- 好,用子查询
SELECT * FROM users 
WHERE id >= (SELECT id FROM users LIMIT 100000, 1)
LIMIT 10;

6. 大表拆小

单表数据量超过千万行,性能会下降。可以:

  • 按时间分表
  • 按用户ID分库
  • 归档历史数据

7. 总结

慢查询优化的核心思路:先找慢 SQL,再分析执行计划,然后加索引或改写 SQL。优化完记得对比前后效果,确保真的变快了。


emer 发布于  2026-10-4 10:41 
'); })();