MySQL中慢SQL的查询及原因分析

2020-12-15  本文已影响0人  nitricoxide

准备数据


查看系统变量

SHOW VARIABLES LIKE 'slow_query%';
SHOW VARIABLES LIKE 'long_query_time';

修改系统变量

SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time=0.001;

执行修改语句后如果再次查询没有生效,重新打开个窗口再次查询就可以了。

测试结果

执行查询语句

select * from student;

slow.log中的记录

select * from student;
# Time: 2020-08-04T06:09:07.716447Z
# User@Host: root[root] @ localhost [::1]  Id:    13
# Query_time: 0.001787  Lock_time: 0.000417 Rows_sent: 2  Rows_examined: 1024
SET timestamp=1596521347;

再次测试更新语句

UPDATE student SET `name` = '李四' WHERE id = 999;
> Affected rows: 1
> 时间: 0.004s

发现也被记录了

UPDATE student SET `name` = '李四' WHERE id = 999;
# Time: 2020-08-04T06:25:11.808408Z
# User@Host: root[root] @ localhost [::1]  Id:    13
# Query_time: 0.001236  Lock_time: 0.000092 Rows_sent: 356  Rows_examined: 712
SET timestamp=1596522311;

sql执行分析

EXPLAIN

Explain 可以获取 MySQL 中 SQL 语句的执行计划,比如语句是否使用了关联查询、是否使用了索引、扫描行数等。可以帮我们选择更好地索引和写出更优的 SQL 。

使用方法:在查询语句前面加上 explain 运行就可以了。

EXPLAIN UPDATE student SET `name` = '李' WHERE id = 999;
EXPLAIN字段详解
列名 描述
id 在一个大的查询语句中每个SELECT关键字都对应一个唯一的id
select_type SELECT关键字对应的哪个查询的类型
table 表名
partitions 匹配的分区信息
type 针对单表的访问方法
possible_keys 可能用到的索引
key 实际上使用的索引
key_len 实际使用到的索引长度
ref 当使用索引列等值查询时,与索引列进行等值匹配的对象信息
rows 预估的需要读取的记录条数
filtered 某个表经过搜索条件过滤后剩余记录条数的百分比
Extra 一些额外的信息
select_type详解
select_type的值 解释
SIMPLE 简单查询(不使用关联查询或子查询)
PRIMARY 如果包含关联查询或者子查询
UNION 联合查询中第二个及后面的查询
DEPENDENT UNION 满足依赖外部的关联查询中第二个及以后的查询
UNION RESULT 联合查询的结果
SUBQUERY 子查询中的第一个查询
DEPENDENT SUBQUERY 子查询中的第一个查询,并且依赖外部查询
DERIVED 用到派生表的查询
MATERIALIZED 被物化的子查询
UNCACHEABLE SUBQUERY 一个子查询的结果不能被缓存,必须重新评估外层查询的每一行
type详解

查询性能从上到下依次是最好到最差

type的值 解释
system 查询对象表只有一行数据,且只能用于MyISAM和Memory引擎的表,这是最好的情况
const 基于主键或唯一索引查询,最多返回一条结果
eq_ref 表连接事基于主键或非NULL的唯一索引完成扫描
ref 基于普通索引的等值查询,或者表间等值连接
fulltext 全文检索
ref_or_null 表连接类型是ref,但进行扫描的索引列中可能包含NULL值
index_merge 利用多个索引
unique_subquery 子查询中使用唯一索引
index_subquery 子查询中使用普通索引
range 利用索引进行范围查询
index 全索引扫描
extra详解
Extra常见的值 解释
Using filesort 将用外部排序而不是索引排序,数据较小时从内存排序,否则需要在磁盘完成排序
Using temporary 需要创建一个临时表来存储结构,通常发生对没有索引的列进行GROUP BY时
Using index 使用覆盖索引
Using where 使用where语句来处理结果
Impossible WHERE 对where子句判断的结果总是false而不能选择任何数据
Using join buffer 改值强调了在获取连接条件时没有使用索引,并且需要连接缓冲区来存储中间结果。如果出现了这个值,那应该注意,根据查询的具体情况可能需要添加索引来改进能。
Using index condition 先条件过滤索引,再查数据
Select tables optimized away 使用某些聚合函数(比如max、min)来访问存在索引的某个字段
上一篇下一篇

猜你喜欢

热点阅读