Explain详解与索引最佳实战
2023-07-03 12:29:51 2 举报
Explain详解与索引最佳实战
作者其他创作
大纲/内容
explain各个列的信息
<b style="">id列:</b> id列的编号是 select 的序列号,有几个 select 就有几个id,<font color="#ff0000">id越大执行优先级越高</font>,id相同从上往下执行,id为nul最后执行<br>
<b>select_type列:</b> 表示对应行是简单还是复杂的查询
simple:简单查询。查询不包含子查询和union
primary:复杂查询中最外层的 select
subquery:包含在 select 中的子查询(不在 from 子句中)
derived:包含在 from 子句中的子查询。MySQL会将结果存放在一个临时表中,也称为派生表<br>
union:在 union 中的第二个和随后的 select
<b>table列:</b>这一列表示 explain 的一行正在访问哪个表
<b style="color: rgb(211, 47, 47);">type列:</b><font color="#000000">这表示关联类型或者访问类型,</font><font color="#ff0000"><b>system > const > eq_ref > ref > range > index > ALL(全表扫描),一般保证达到range级别,最好达到ref</b></font>
null:mysql能够在优化阶段分解查询语句,在执行阶段用不着再访问表或索引
const::mysql可以对查询部门优化并将其转化为一个常量,一般是在主键作为条件,表里只有一行匹配时
system:const的特例,表里只有一数据且符合const时为system
eq_ref:关联查询中使用<b>主键关联</b>时,该查询为eq_ref
ref:使用<b>普通索引或者唯一索引的部分前缀</b>时,可能找到多行符合的结果时
range:范围查询走索引,<font color="#000000" style="font-weight: bold;">in(), between ,> ,<, >=,</font><font color="#ff0000" style=""><b><i><u>(优化到range级别)</u></i></b></font>
index:扫描全索引就能拿到结果一般指扫描二级索引,使用覆盖索引时
ALL:全表扫描
<b>possible_keys列</b>:可能用到的索引
<b>key列</b>:sql语句运行时用到的索引
<b>key_len列:</b>在使用联合索引时可以根据使用索引的大小判断使用了联合索引的什么字段
<b><i>key_len计算规则:</i></b>
char(n):n字节长度
<b><font color="#ff0000">varchar(n):如果是utf-8,则长度 3n + 2 字节,加的2字节用来存储字符串长度</font></b>
tinyint:1字节
smallint:2字节
int:4字节
bigint:8字节
date:3字节
timestamp:4字节
datetime:8字节
<font color="#ff0000"><b>如果字段允许为 NULL,需要1字节记录是否为 NULL</b></font>
<b>索引最大长度是<font color="#d32f2f">768</font>字节,当字符串过长时,mysql会做一个类似左前缀索引的处理,将前半部分的字符做索引</b>
<b>ref列:</b>这一列显示了在key列记录的索引中,表查找值所用到的列或常量
<b>rows列:</b>Mysql<b>估计</b>查询的行数,<b>不是结果集的行数</b>,有可能一样
<b>Extra列:</b>
<b>Using index</b>:使用覆盖索引
Using where:使用 where 语句来处理结果,并且查询的列未被索引覆盖
Using index condition:查询的列不完全被索引覆盖,where条件中是一个前导列的范围
Using temporary:mysql需要创建一张临时表来处理查询
<b><font color="#b71c1c">索引优化原则</font></b>
<b>全值匹配:联合索引尽量<font color="#ff0000">所有索引</font>字段都使用</b>
.<b>最左前缀法则:查询从索引的最左前列开始并且不跳过索引中的列</b>
<b>不在索引列上做任何操作(<font color="#b71c1c">计算、函数、(自动or手动)类型转换</font>),会导致索引失效而转向全表扫描</b>
<b>存储引擎不能使用索引中范围条件右边的列。为什么?<font color="#b71c1c">因为索引是有序的!!!范围右边列不能保证有序</font></b>
<b>尽量使用<font color="#ff0000">覆盖索引</font>(只访问索引的查询(索引列包含查询列)),减少 select * 语句</b>
<b>mysql在使用不等于(<font color="#b71c1c">!=或者<></font>)的时候无法使用索引会导致全表扫描</b>
<b><font color="#d32f2f">is null,is not null</font> 一般情况下也无法使用索引</b>
<b>like以<font color="#b71c1c">通配符开头('$abc...')</font>mysql索引失效会变成全表扫描操作,<font color="#b71c1c">非要用前置$</font>可以使用覆盖索引优化</b>
<b style=""><font color="#000000">字符串不加单引号索引失效</font><font color="#b71c1c">,mybatis不使用${}的原因又多了一个,${}的值不加单引号</font></b>
<b>少用<font color="#b71c1c">or或in</font>,用它查询时,mysql不一定使用索引</b>
<b>范围查询优化,给经常使用范围查询的列建索引</b>
0 条评论
下一页