使用EXPLAIN关键字可以模拟优化器执行sql语句,从而看到sql的执行过程,分析sql的查询或者表结构的性能瓶颈。
EXPLAIN如何使用?
- 格式:EXPLAIN SQL语句
EXPLAIN SELECT * FROM t1;
- 执行结果:
EXPLAIN字段含义:
- id:select查询的序列号,表示查询或者子查询操作表的顺序。id越大越优先执行。
EXPLAIN SELECT t1.id FROM t1 WHERE t1.id IN
(SELECT t2.id FROM t2 WHERE t2.id IN
(SELECT t3.id FROM t3 WHERE t3.content = '')
);
正常来说,子查询的顺序应该是在外层查询之前的,也就是说操作t3表的sql的id应该大于操作t1表的id才对。但是在mysql5.7的版本中,优化器右在内部做了优化,id显示的都是1,表示同步执行。
- select type:区别普通查询、连接查询、子查询等复杂查询。
-- 普通查询,其中SIMPLE表示普通查询
EXPLAIN select * from t1 ;
-- where子句包含子查询,其中PRIMARY用来表示外层查询
-- SUBQUERY表示where子句包含了子查询
EXPLAIN select t2.id from t2 where t2.id =
( select t3.id from t3 where t3.id = 1);
- type:查询的访问类型,比较重要的指标。从好到坏依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
一般来说,sql至少保证达到range级别,最好能达到ref。
-- eq_ref:唯一索引扫描。对于每个索引键,表中只有一条记录与之匹配。
-- 比如:id
EXPLAIN SELECT * FROM t1 ,t2 WHERE t1.id = t2.id ;
-- ref:返回可以匹配某一列某个值的所有行。
CREATE INDEX idx_t2_content ON t2(content);
EXPLAIN SELECT * FROM t1 ,t2 WHERE t1.content = t2.content;
-- range:只检索某个范围内的数据。key列显示的就是使用的什么索引。
EXPLAIN select * from t1 where t1.id >10 ;
-- index:有索引但是没有使用索引进行过滤
EXPLAIN select id from t1;
-- all:全盘扫描
EXPLAIN SELECT * FROM t1 ;
- key:实际使用的索引。
- key_len:索引中使用的字节数。key_len越长,表示索引使用的越充分。
- ref:显示索引的哪一列被使用了。
CREATE INDEX idx_name_t_emp ON t_emp(NAME);
EXPLAIN SELECT * FROM t_emp emp ,t_dept dept WHERE emp.name = 'aaa' AND emp.deptId = dept.id ;
- rows:执行查询时可能要查询的行数(不精确),越少越好。