explain(执行计划) 命令
使用 explain 命令可以查看 SQL 执行的具体细节。
例如:
explain SELECT * FROM `表名称`
得到如下结果
a1affd45fa844d3080489c46c84b5cfb[1].png其中各个参数的含义分别是
-
id
:查询的序列号,包含一组数字,有如下三种情况:- id相同:执行顺序(表顺序)由上至下
- id不同,但查询时子查询,此时id的序号会递增,id值越大优先级越高,越先被执行;
- id相同和id不同同时存在,id 大的先执行,id 相同的从上到下执行。
-
select_type
:查询类型,一般有SIMPLE
,PRIMARY
,UNION
,SUBQUERY
; -
table
:表或者衍生表名称; -
partitions
:显示表的分区名; -
type
:表的连接类型,按照性能排序分别为system
>const
>eq_ref
>re
>ref_or_null
>index_merge
>unique_subquery
>unique_subquery
>range
>index
>all
; -
possible_keys
:查询时,能够使用的索引; -
key
:真正使用的索引; -
key_len
:索引长度; -
ref
:索引的哪一列被使用; -
rows
:扫描的行数,越少越好; -
filtered
:存储引擎返回的数据在服务层过滤后,剩下满足过滤条件的百分比,值越大越好; -
Extra
:执行情况的说明。
其中 type
字段很重要,表示的查询性能,其值也比较多,上文只是概述,下面详细说明。
-
system
:表仅有一行,系统表,一般出现不了; -
const
:通过索引一次查找到数据; -
eq_ref
:每条记录只有一行; -
ref
:类似上述内容,但使用的是普通索引; -
fulltext
:全文索引; -
ref_or_null
:同上,包含对 NULL 查询; -
index_merge
:索引合并优化; -
unique_subquery
:in
语句包含一个查询主键字段的查询; -
index_subquery
:in
语句后面是非唯一索引字段的查询; -
range
:范围查询,一般在 where 语句使用了between
,<
,>
,in
; -
index
:数据是通过查询索引得到的数据; -
all
:全表扫描。
要保证
sql
查询,一般要达到range
或ref
级别。
上述列名 Extra
可能会包含如下值。
-
using index
:查询使用了索引,出现表示好; -
using where
:查询结果使用了过滤; -
using temporary
:使用了临时表; -
using filesort
:使用一个外部的索引排序,建议优化,原因一般如下:-
order by
的字段不是索引字段; -
select
查询字段不全是索引字段; -
select
查询字段都是索引字段,但order by
字段和索引字段的顺序不一致。
-
-
using join buffer
:使用了连接缓存; -
impossible where
:where 语句查询不到数据; -
const row not found
:目标表是空的; -
Deleting all rows
:对于DELETE
语句,例如 MyISAM 引擎支持以简单而快速的方式删除所有的数据; -
Distinct
:查找distinct
值,当找到第 1 个匹配的行后,停止查找; -
Impossible HAVING
:HAVING 子句始终为 False; -
Impossible WHERE
:WHERE 子句始终为 False;
基于此可以对比一下使用主键查询和不使用主键查询的差别。
explain SELECT * FROM p_subject_sort
explain SELECT * FROM p_subject_sort where id = 1
918574b01700445db12523d783184375[1].png
同时还可以添加联合索引提高查询效率,但如果在查询的时候,使用了其它函数操作,则索引失效,另一种情况是数据库查询的时候使用 !=
, <>
, is null
, is not null
, like 关键字%
等也会导致索引失效,不过这些的前提是原来的查询就用到了索引。
SQL查询优化
基于上述内容,可得优化结论如下:
- 避免全表扫描,
type
出现all
,尽量在where
,order by
涉及的列上建立索引。 - 不要编写
select *
,要明确查询字段; -
!=
,<>
,like
模糊查询会导致全表扫描,如果无法避免,可以建立全文索引; -
遵循最左原则,例如在
where
子句中写查询条件时,优先选择索引字段; - 能使用关联查询(LEFT JOIN)的尽量不要使用子查询,能不使用关联查询的就不要使用关联查询;
- 要习惯使用
limit
限制查询条目。
记录时间
今天是持续写作的第 <font color=red>285</font> / 365 天。
可以<font color=#04a9f4>关注</font>我,<font color=#04a9f4>点赞</font>我、<font color=#04a9f4>评论</font>我、<font color=#04a9f4>收藏</font>我啦。
更多精彩
网友评论