Explain关键字使用
explain select * from film where id = 1;
字段详解
id
- id相同时,执行顺序是由上向下
id不相同时,表示会包含子查询,id 值会递增。id 值越大,优先级越高,越先执行。
select_type
SIMPLE:简单查询,不包含 UNION 或者子查询。
- PRIMARY:查询中如果包含子查询或其他部分,外层的SELECT 将被标记为 PRIMARY。
- SUBQUERY:子查询中的第一个 SELECT。
- UNION:在 UNION 语句中,UNION 之后出现的 SELECT。
- DERIVED:在 FROM 中出现的子查询将被标记为 DERIVED。
-
table
这一列表示 explain 的一行正在访问哪个表。 当 from 子句中有子查询时,table列是 格式,表示当前查询依赖 id=N 的查询,于是先执行 id=N 的查询。
当有 union 时,UNION RESULT 的 table 列的值为,1和2表示参与 union 的 select 行id。
当table这列为NULL时,mysql能够在优化阶段分解查询语句,在执行阶段用不着再访问表或索引。partitions
type
查询执行的类型,描述了查询是如何执行的。所有值的顺序从最优到最差排序为:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
编写查询语句时,至少要保证range以上的类型。system
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
索引问题
- 条件字段函数操作
- 隐式类型转换
- 隐式字符编码转换
MVCC
https://segmentfault.com/a/1190000037557620

