Explain关键字使用

  1. explain select * from film where id = 1;

image.png

字段详解

id

  • id相同时,执行顺序是由上向下
  • id不相同时,表示会包含子查询,id 值会递增。id 值越大,优先级越高,越先执行。

    select_type

  • SIMPLE:简单查询,不包含 UNION 或者子查询。

  • PRIMARY:查询中如果包含子查询或其他部分,外层的SELECT 将被标记为 PRIMARY。
  • SUBQUERY:子查询中的第一个 SELECT。
  • UNION:在 UNION 语句中,UNION 之后出现的 SELECT。
  • DERIVED:在 FROM 中出现的子查询将被标记为 DERIVED。
  • UNION RESULT:UNION 查询的结果。

    table

    这一列表示 explain 的一行正在访问哪个表。 当 from 子句中有子查询时,table列是 格式,表示当前查询依赖 id=N 的查询,于是先执行 id=N 的查询。
    当有 union 时,UNION RESULT 的 table 列的值为,1和2表示参与 union 的 select 行id。
    当table这列为NULL时,mysql能够在优化阶段分解查询语句,在执行阶段用不着再访问表或索引。

    partitions

    查询所匹配记录所在的分区,对于未分区的表,值为 NULL。

    type

    查询执行的类型,描述了查询是如何执行的。所有值的顺序从最优到最差排序为:
    system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
    编写查询语句时,至少要保证range以上的类型。

    system

    表中只有一行数据,是 const 的一种特例。

    const

    表中最多只有一行匹配的记录,一次查询就可以找到,常用于使用主键或唯一索引的所有字段作为查询条件。

    eq_ref

    当连表查询时,前一张表的行在当前这张表中只有一行与之对应。是除了 system 与 const 之外最好的 join 方式,常用于使用主键或唯一索引的所有字段作为连表条件。

    ref

    使用普通索引作为查询条件,查询结果可能找到多个符合条件的行。

    fulltext

    查询使用到了全文索引。

    index_merge

    当查询条件使用了多个索引时,表示开启了 Index Merge 优化,此时执行计划中的 key 列列出了使用到的索引;ken_len 列列出了所使用的索引的长度。

    range

    对索引列进行范围查询,执行计划中的 key 列表示哪个索引被使用了,key_len 列表示使用的索引的长度。

    index

    查询遍历了整棵索引树,与 ALL 类似,只不过扫描的是索引,而索引一般在内存中,速度更快。

    ALL

    查询遍历全表,很可能要读磁盘,速度最慢。

    possible_keys

    列出查询中可能被使用到的一个或多个索引,不一定被查询实际使用。

    key

    查询中实际使用到的索引。如果为 NULL,则表示未建立索引或索引失效。

    key_len

    表示查询索引时使用的字节数,在满足需求的前提下越短越好。

    ref

    这一列显示了在key列记录的索引中,表查找值所用到的列或常量,常见的有:const(常量),字段名(例:表名.id)

    rows

    展示 MySQL 估算出的查询时需要遍历的行数,越少越好。不是实际返回的结果行。

    filtered

    表示估算的经过查询条件删选出的列数的百分比。例如 rows 是 1000,filtered 是 50(50%),则实际筛选出的列数为 1000 * 50% = 500。

    Extra

    这一列包含了 MySQL 在查询时的一些额外信息。
    特别注意,当 Extra 列包含 Using filesort 或 Using temporary,MySQL 的性能会存在问题,需要尽可能避免。
    Extra 列常见的信息如下:

  • Using filesort

在排序时使用了外部的索引排序,没有用到表内索引进行排序。主要就是没有使用索引排序

  • Using temporary

MySQL 需要创建临时表来存储查询的结果,常见于 ORDER BY 和 GROUP BY。

  • Using index

表明查询使用了覆盖索引,不用回表,查询效率非常高。

  • Using where

表明查询使用了 WHERE 子句进行条件过滤。一般在没有使用到索引的时候会出现。
需要注意的是如果不是特意进行全表扫描,例如 select * from member,那么如果 Extra 中没有 Using where,且 type 列的值是 ALL 或者 index,则表示查询中有错误,需要排查。

  • Impossible WHERE

表示 WHERE 子句的结果总是 false 且无法查到任意行。

  • Using join buffer (Block Nested Loop)

连表查询的方式,表示当被驱动表的没有使用索引的时候,MySQL 会先将驱动表读出来放到 join buffer 中,再遍历被驱动表与驱动表进行查询,具体见 MySQL JOIN 的内容。mysql 8.0.18 增加了 hash join 算法

  • Using join buffer (Batched Key Access)

连表查询的方式,与 Using join buffer (Block Nested Loop) 类似。
MySQL 在链表查询时使用了 BKA 算法。

一条SQL的执行过程

SELECT DISTINCT <select_list> FROM <left_table> <join_type> JOIN <right_table>
ON <join_condition> WHERE <where_condition> GROUP BY <group_by_list>
HAVING <having_condition> ORDER BY <order_by_condition> LIMIT <limit_number>

LEFT JOIN ON 语句条件 和 WHERE 加语句条件的区别

MySQL锁

共享锁与排他锁

  • 共享锁(读锁):其他事务可以读,但不能写。
  • 排他锁(写锁) :其他事务不能读取,也不能写。


https://zhuanlan.zhihu.com/p/29150809

索引问题

image.png