explain详解

    explain(Execution plan cost)就是优化器做的事情。执行计划,很重要!!
    只有明白sql是如何执行的,才能更好的优化,先了解它,然后才能优化它,explain就是和mysql优化对话的大门和打开优化器门的钥匙~
问题导读:
  • MySQL一定是按照我们输入的sql执行的吗?
  • 如果不是,那么是如何优化和选择索引的呢?
  • 如何知道MySQL使用了我们创建的那个索引,扫描的行数及是否排序情况?

1、认识explain

认识explain:可以模拟mysql优化器来执行sql语句,从而让我们知道db是如何执行sql的。分析sql和表结果的性能瓶颈。
实操, 语法: explain +sql

1.1、Id:表的读取顺序

Id 查询的序列号,一组数字,表示查询中执行的select字句或操作表的顺序
  • 相同:自上而下
  • 不相同:id号越大优先级越高,先执行;
  •  相同又不同的子查询顺序满足1-2, 小表驱动大表
 

1.2、Select_type: sql的操作类型

Select type 查询类型,主要用于区别 普通查询/联合查询/子查询等的复杂查询
  • Simple:简单的select查询,查询中不包含子查询或者UNION
  • Primary: 查询中包含任何复杂的字部分,最外层查询被标记为:
  • SUBQUERY:  select或where中包含的子查询
  • Deriverd: 在from中包含的子查询被标记为driverd(衍生),不是真实的表;
  • Union:第二个selet出现union后将标记为nuion;
  • Union result:是对两个sql语句的结果的一个结果合并;

1.3、table:操作的表名称

table:显示这一行的数据属于那张表

1.4、type:索引类型 system > const > eq_ref >( ref >  range )> index > all 

type system > const > eq_ref >(  ref >  range  )> index > all 
System: 表只有一行记录,例如系统表;比如lock等待的时间query_lock_wait/long_query_time
const:   指常量查询比如 id = 1  使用主键或者唯一索引等值查询一次命中,因为只匹配一行;
eq_ref:  唯一索引命中,常见于主键索引和唯一索引扫描本表或者关联表, 非常量查询;通过唯一的索引值来匹配,表中只有一条记录与之匹配;
Ref: 查询索引,使用了条件索引,非唯一性索引。 返回一条或多条纪录, 非唯一性索引扫描,返回匹配某个单独值的所有行;本质上也是一种索引访问,它返回所有匹配某个单独值的行,然而,他可能会找到多个符合条件的行,所以它属于 查找和扫描的混合体
 
range:   对索引使用了范围查询 只检索给定范围的行,使用一个索引来选择行,key列显示使用那个索引。一般就是在你的where语句中出现 between/</>/in等查询的时候,这种 范围扫描索引扫描比全表扫描要好,因为它只需要开始于索引的某一点,而结束另一点,不用扫描全部索引。
Ps:如果id不是表的 in 范围内的,就退化为all了。
 
Index:查询了所有索引的值 只是不去扫描整个数据文件; 覆盖索引
 
all:标上没有索引,扫描所有的数据

1.5、 possable key: 可能用到的索引-key

案例:possible key为空,但是key使用了索引,实际上是用到了覆盖索引。

1.6、key实际用到的key如果为null,则没有使用索引

Ps: 注意一下possable_key没有值,key有值的情况;

1.7、Ken_len:  索引使用的字节数

key_len:表示索引中使用的字节数,可通过该列计算查询中使用的索引长度。在不损失精确性的情况下,长度越短越好;
  • 显示的 值为索引字段的最大可能长度,并非实际使用长度,即  key_len 是根据表初定义计算而得,不是通过表内检索内容得出。 
  • 可以用来判断复合索引是否实效的关键指标。我们可以通过该索引的长度大小来看使用了那些索引。
  • char 和 vchar类型:latin 占用1个字节 ,gbk 占用2个字节, utf8 占用 3 个字节
字节大小的计算:
  • char(10)   null  30 + 1;
  • varchar(10) +  null 30 + 2 (字段长度) +1
Utf-8和utf8mb4
  •  为了获取更好的兼容性,应该总是使用 utf8mb4 而非 utf8. 
  •  对于 CHAR 类型数据,utf8mb4 会多消耗一些空间,根据 Mysql 官方建议,使用 VARCHAR  替代 CHAR。
小结:
  • 复合索引有最左前缀的特性,如果复合索引能全部用上,则是复合索引字段的长度之和,这也可以用来判断复合索引是否部分使用,还是全部使用
  • Null都需要一个字节的额外空间来标识该字段是否为空,所以索引字段最好不要为null,因为null让统计更加复杂,并且需要额外的内存空间。
  • 变长varchar字段需要额外的两个字段来存储是否为空和长度;
整数/浮点数/时间类型的索引长度:
  • Not null = 字段本身的字段长度
  • Null = 字段本身的字段长度 + 1 (因为需要有 是否为空的标记,这个标记需要占用一个字节 )
Datetime 5.6 中占用 5 个字节, datetime 5.5 中字段长度为 8 个字节;

1.8、Ref:表之间的引用

ref:显示索引的 具体那一列被使用了。
⚠️: 和type=ref区分开

1.9、rows:扫描的记录行数

rows:根据表统计情况及索引选用情况,大致估算出找到所需的记录所需要扫描的行数; 尽量少。
filtered:得到的结果数据和全部扫描的数据的一个百分比,大约不精确, 越大越好:
  • 例如:70%表示扫描了100行共得到70行有效数据;

2.0、extra:额外信息

  1. using filesort排序可以优化。mysql无法利用索引完成数据的排序;不是按照表内索引顺序读取数据, 无法利用索引的排序称为:文件排序 可能在 次磁盘-(外排序) 或者 内存(内排序)上完成排序,应尽量避免此种情况;
  2. using temporary:mysql 使用了临时表来保存中间结果,常见于排序order by和组查询group by,distinct;
  3. Using index:    使用了索引的排序, 使用了覆盖索引,避免了 回表
  4. using where:表明server使用了 where过滤
  5. using join buffer:使用了连接缓存; select price from order o   INNER JOIN coupon c on o.id = c.orderid;
  6. impossible where:where子句的值总为false,select * from goods where 1=2;
  7. use index condition( push down) 使用了 索引下推
extra实例操作演示:
临时表:
排序:
添加索引:
ALTER TABLE `kinginfo`.`goods` ADD UNIQUE INDEX `create_time_UNIQUE` (`create_time` ASC);
 

2、结束

    认识优化器后,才能更好的掌握sql的执行过程,从而找到优化的点。
 
 
水滴石穿,积少成多。学习笔记,内容简单,用于复习,梳理巩固。
 
##参考资料,
《Innodb存储引擎》
《MySql实战详解》
MySQL中,EXPLAIN是一个关键字,用于查询SQL语句的执行计划和索引使用情况。使用EXPLAIN可以帮助我们了解MySQL如何处理我们的查询语句,并对查询进行优化。 EXPLAIN命令会返回一个包含12列信息的结果集。这些列包括:id,select_type,table,partitions,type,possible_keys,key,key_len,ref,rows,filtered,Extra。每一列都提供了有关查询执行的详细信息。 - id列表示查询的标识符,常用来区分查询的不同部分。 - select_type列表示查询的类型,例如简单查询、子查询、联合查询等。 - table列表示与查询相关的表名。 - partitions列表示查询涉及的分区信息。 - type列表示查询的访问类型,包括全表扫描、索引扫描、范围扫描等。 - possible_keys列表示可能用到的索引。 - key列表示实际使用的索引。 - key_len列表示索引的长度。 - ref列表示查询中使用的索引引用。 - rows列表示查询返回的行数估计值。 - filtered列表示查询结果的过滤率。 - Extra列提供了额外的信息,如是否使用了临时表、是否使用了文件排序等。 通过分析EXPLAIN的结果,我们可以判断查询是否使用了索引,是否存在全表扫描等问题,从而进行查询性能的优化。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Mysqlexplain详解](https://blog.csdn.net/weixin_44143114/article/details/118526637)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [MySQL数据库:第十七章:Explain详解](https://blog.csdn.net/java_wxid/article/details/111881486)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值