更新时间:2022-09-19 10:35:03
explain或者desc获取MySQL如何执行select语句的信息。
结果包含很多列
SELECT标识符。这是查询中SELECT的序列号,表示查询中执行select子句或者操作表的顺序。如果该行引用其他行的并集结果,则该值可为NULL。
id号分为三种情况:
explain se1ect * from emp e join dept d on e.deptno = d.deptno join salgrade sg on e.sa1 between sg.1osal and sg.hisal;
explain select * from emp e where e.deptno in (select d.deptno from dept d where d.dname = 'SALES');
exp1ain select * from emp e join dept d on e.deptno = d.deptno join salgrade sg on e.sa1 between sg.1osal and sg.hisal where e. deptno in (select d.deptno from dept d where d.dname = 'SALES'); select_ type
区分SELECT的类型,是普通查询还是联合查询还是子查询:
输出结果集。对应行正在访问哪个表,表名或者别名,可能是临时表或者union合并结果集。
如果是具体表名,则表明从实际的物理表中获取数据,当然也可是表的别名
表名是derivedN的形式,表示使用了id为N的查询产生的衍生表
当有union result时,表名是union n1,n2等的形式,n1,n2表示参与union的id
type列描述如何连接表。
表示MySQL在表中找到所需行的方式,或者叫访问类型
。
常见类型:all,index,range,ref,eq_ref,const,system,null,性能由差到好。
一般需要保证查询至少达到range级,***能达到ref。
最简单暴力的全表扫描,MySQL遍历全表找到匹配行,效率最差。
对来自先前表的行的每个组合进行全表扫描。若该表是未标记为const的第一个表,则通常不好,并且在所有其他情况下通常性能也非常糟糕。
一般可以通过增加索引来避免ALL,这些索引允许基于早期表中的常量值或列值从表中检索行。
explain select * from film where rating > 9;
连接类型与ALL相同,除了扫描索引树外。这发生于两种方式:
Extra
列显示Using index
。仅索引扫描通常比ALL更快,因索引大小通常小于表数据Using index
。当查询仅使用属于单个索引一部分的列时,MySQL可以使用此连接类型。
explain select title from film;
使用索引查询行,仅检索给定范围内的行。
key
列指示使用的哪个索引。key_len
包含使用的最长的键部分。
此类型的ref
=NULL
。
当使用 =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, LIKE, or IN()
操作符将key
列与常量进行比较时,可以使用range:
索引范围扫描,常见<,<=,>,>=,between
SELECT * FROM tbl_name WHERE key_column = 10; SELECT * FROM tbl_name WHERE key_column BETWEEN 10 and 20; SELECT * FROM tbl_name WHERE key_column IN (10,20,30); SELECT * FROM tbl_name WHERE key_part1 = 10 AND key_part2 IN (10,20,30);
此连接类型类似于unique_subquery。它代替了IN
子查询,但适用于以下形式的子查询中的非唯一索引:
value IN (SELECT key_column FROM single_table WHERE some_expr)
此类型将eq_ref替换为以下形式的某些IN子查询:
value IN (SELECT primary_key FROM single_table WHERE some_expr)
unique_subquery只是一个索引查找函数,可以完全替换子查询以提高效率。