查看SQL执行频率
MySQL 客户端连接成功后,通过show[session|global] status 命令可以提供服务器状态信息。通过如下指令可以查看当前数据库的INSERT
、UPDATE
、DELETE
、SELECT
的访问频次:
|
|
结果如下:
|
|
查询慢日志
慢查询日志记录了所有执行时间超过指定参数(long_query_time,单位:秒,默认10秒)的所有SQL语句的日志。MySQL的慢查询日志默认没有开启,执行一下SQL查看慢日志开启状态:
1
SHOW VARIABLES LIKE 'slow_query_log';
需要在MySQL的配置文件(/etc/my.cnf)中配置如下信息:
|
|
重启MySQL服务,本机环境为win10的WSL2,直接执行以下命令:
|
|
profile详情
show profiles
能够在做SQL优化时帮助我们了解时间都耗费到哪去了。通过have_profiling
参数,能够看到当前MySQL是否支持profile操作:
|
|
默认profiling
是关闭的,可以通过set
语句在session
/global
级别开启profiling
:
|
|
执行完查询语句后再执行show profiles
,结果如下:
|
|
explain 执行计划
EXPLAIN
或者 DESC
命令获取MySQL如何执行SELECT语句的信息,包括在SELECT语句执行过程中表如何连接和连接的顺序。语法如下:
|
|
结果如下:
|
|
EXPLAIN
输出列如下:
Column | JSON Name | Meaning |
---|---|---|
id | select_id |
SELECT 标识符 |
select_type | None |
SELECT 类型 |
table | table_name |
输出行table |
partitions | partitions |
匹配的分区 |
type | access_type |
连接类型 |
possible_keys | possible_keys |
可能的索引选择 |
key | key |
实际选择的索引 |
key_len | key_length |
所选键的长度 |
ref | ref |
与索引比较的列 |
rows | rows |
估计要检查的行 |
filtered | filtered |
按table条件过滤的行百分比 |
Extra | None |
扩展信息 |
😀 Note 详细解释可参考 [官方文档]
-
id
行标识,如果没有子查询或者联合查询,这个值是1,id列值越大越先执行,如果一样大,那么就从上往下依次执行 -
select_type
查询的类型,可以是下表的任何一种类型select_type 类型说明 SIMPLE
简单 SELECT
(不使用UNION
或子查询)PROMARY
最外层的 SELECT
UNION
UNION
中第二个或之后的SELECT
语句DEPENDENT UNION
UNION
中第二个或之后的SELECT
语句取决于外面的查询UNION RESULT
UNION
的结果SUBQUERY
子查询中的第一个 SELECT
DEPENDENT SUBQUERY
子查询中的第一个 SELECT
,取决于外面的查询DERIVED
衍生表(FROM自居中的子查询) MATERIALIZED
物化子查询 UNCACHEABLE SUBQUERY
结果集无法缓存的子查询,必须重新评估外部查询的每一行 UNCACHEABLE UNION
UNION
中第二个或之后的SELECT
,属于无法缓存的子查询
⭐
DEPENDENT
意味着使用了关联子查询
-
table
:输出行所引用表的名称,也可以是以下值之一:- <unionM,N>: 引用id为M和N UNION之后的结果。
: 引用id为N的结果派生出的表,派生表可以是一个结果集,例如派生自FROM中子查询的结果。 : 引用id为N的子查询结果物化得到的表,即生成一个临时表保存子查询的结果。
-
partitions
:v5.7之前该项是explain partitions
显示的选项,v5.7之后成为了默认选项,该列显示的为分区表中的分区情况,非分区表该字段为空(null)。 -
type( 重要 ):连接类型
-
system
表中只有一行数据或者是空表,这是const类型的一个特例,且只能用于MyISAM
和Memory
表,如果是InnoDB
引擎表,type
列在这个情况通常都是all
或者index
-
const
最多只有一行记录匹配。当联合主键或唯一索引的所有字段跟常量值比较时,join
类型为const
。其他数据库也叫做唯一索引扫描 -
eq_ref
多表join
时,对于来自前面表的每一行,在当前表中只能找到一行,这可能是除了system
和const
之外最好的类型,当主键或唯一非NULL索引的所有字段都被当做join
连接时会出现此类型。eq_ref
可用于使用’=‘操作符作比较的索引列,比较的值可以是常量,也可以是使用此表之前读取的表的列表达式。 -
ref
对于来自前面表的每一行,在此表的索引中可以匹配到多行,若连接只用到索引的最左前缀或索引不是主键或唯一索引时,使用ref
类型(也就是说,此类型能够匹配到多行连接)。ref
可用于使用=
或<=>
操作符作比较的索引列。 -
fulltext
用于全文索引的时候是这个类型,要注意,全文索引的优先级很高,若全文索引和普通索引同时存在,mysql不管代价,优先选择使用全文索引 -
ref_or_null
类似于ref
类型,只是增加了null
值得比较,实际用的不多 -
index_merge
此类型表示查询使用两个以上索引,最后取交集或者并集,常见and
,or
的条件使用了不同的索引,官方排序这个在ref_or_null
之后,但是实际上由于要读取多个索引,性能可能大部分时间都不如range
。 -
unique_subquery
用于WHERE
中的IN
形式子查询,子查询返回不重复值唯一值,可以完全替换子查询,效率更高。 该类型替换了下面形式的IN
子查询的ref
:value IN (select primary_key FROM single_table WHERE some_expr)
-
index_subquery
该连接类型类似于unique_subquery
。适用于非唯一索引,可以返回重复值 -
range
索引范围查询,常见于使用=
<>
>
>=
<
<=
IS NULL
<=>
BETWEEN
IN
或者LIKE
等运算符的查询中。 -
index
索引全表扫描,把索引从头到尾扫一遍。这里包含两种情况: 一种是查询使用了覆盖索引,那么它只需要扫描索引就可以获得数据,这个效率要比全表扫描要快,因为索引通常比数据表小,而且还能避免二次查询。在extra
中显示Using index
,反之,如果在索引上进行全表扫描,没有Using index
的提示。 -
all
全表扫描,性能较差
-
-
possible_keys:查询可能用到的索引,如果此列是
NULL
,则没有用到索引。 -
key:表示MySQL实际决定使用的索引,如果MySQL决定使用其中一个
possible_keys
索引来查找行,则该索引将作为键值列出。 -
key_length:查询用到的索引长度(字节), 如果是单列索引,那就整个索引长度算进去,如果是多列索引,那么查询不一定都能使用到所有的列,用多少算多少。例如组合索引为
idx_username_create_time
,当查询语句为select * from user where username='qqq'
时,只用到了username
字段,那么key_len
只会计算username
字段占用的字节数,假如username
字段类型为varchar(50)
NOT NULL,字符编码为utf8mb3
(utf8编码一个字符占用3个字节,gbk编码一个字符占2字节),记录字符串长度占用2字节,记录字段不为空占用1字节(若没有NOT NULL
限制则不占用这1个字节)那么key_len
为 50 * 3 + 2 + 1 = 153字节 -
ref:如果使用的是常数等值查询,这里会显示
const
,如果是连接查询,被驱动表的执行计划这里会显示驱动表的关联字段,如果是条件使用了表达式或者函数,或者条件列表发生了内部隐式转换,这里可能显示为func
。 -
rows( 重要 ):
rows
也是一个重要的字段,这是MySQL估算的需要扫描的行数(不是精确值)。这个值非常直观显示SQL的效率好坏,原则上rows
越少越好。 -
filtered:该字段表示存储引擎返回的数据在server层过滤后,剩下多少满足查询的记录数量的比例,注意是百分比,不是具体记录数。
-
Extra( 重要 ):
EXPLAIN
中很多额外的信息会在Extra
字段显示,常见的有以下:distinct
: 在select
部分使用了distinct
关键字Using filesort
: 当Extra
中有Using filesort
时,表示MySQL需额外的排序操作,不能通过索引顺序到达排序效果,一般有Using filesort
都建议优化去掉,因为这样的查询CPU资源消耗较大。Using index
: “覆盖索引扫描”,表示查询在索引树种就可查找所需数据,不用扫描表数据文件,往往说明性能不错。Using temporary
: 查询有使用临时表,一般出现于排序,分组和多表join的情况,查询效率不高,建议优化。