explain可以查看sql的执行计划,根据执行计划,可以看出sql慢在哪,方便进行调优。
explain中比较重要的几个字段:type、key、key_len、rows、filtered、Extra。以下列举比较常见的情况
type取值,一般而言从上到下性能依次降低
CREATE TABLE `test` (
`a` int NOT NULL AUTO_INCREMENT,
`b` int DEFAULT NULL,
`c` int DEFAULT NULL,
PRIMARY KEY (`a`),
KEY `b` (`b`)
) ENGINE=InnoDB;
insert into test (a,b,c) values (1,1,1), (2,2,2),(3,3,3),(4,4,4),(5,5,5),(6,6,6),(7,7,7);
CREATE TABLE `test_explain` (
`id` int NOT NULL AUTO_INCREMENT,
`index_unique` int DEFAULT null,
`index` int DEFAULT NULL,
`index_joint_1` int default null,
`index_joint_2` int default null,
`index_joint_3` int default null,
`no_index_1` int DEFAULT NULL,
PRIMARY KEY (`id`),
unique key `index_unique` (`index_unique`),
key `index` (`index`),
key `idx_joint` (`index_joint_1`, `index_joint_2`, `index_joint_3`)
) ENGINE=InnoDB;
insert into test_explain (id, index_unique, `index`, index_joint_1, index_joint_2, index_joint_3, no_index_1)
VALUES (1, 1, 1, 1,1,1,1), (2,2,2,2,1,1,2),(3,3,3,3,1,2,3), (4,4,4,4,1,2,4), (5,5,5,5,1,3,5), (6,6,6,6,6,6,6),(7,7,7,7,7,7,7);
-- 使用一个值,通过主键、唯一索引精确匹配一条记录
-- type=const, Extra=
explain select * from test_explain where id = 1;
-- type=const, Extra=
explain select * from test_explain where id = 1 and index_unique = 1;
-- type=const, Extra=
explain select * from test_explain where id = 1 and `index` = 1;
-- type=const, Extra=
explain select * from test_explain where index_unique = 1;
-- 使用一个值,通过主键、唯一索引精确匹配一条记录,发生索引覆盖,不回表
-- type=const, Extra=Using index
explain select index_unique from test_explain where index_unique = 1;
-- 连表查询, 使用主键或者唯一键进行关联
-- type=ALL, type=eq_ref
explain select * from test t left join test_explain te on te.index_unique = t.b;
-- type=ALL, type=eq_ref
explain select * from test t, test_explain te where te.index_unique = t.a;
-- type=ALL, type=eq_ref
explain select * from test t left join test_explain te on te.id = t.b;
-- type=ALL, type=eq_ref
explain select * from test t, test_explain te where te.id = t.a;
-- type=ALL, type=eq_ref
explain select * from test t left join test_explain te on te.index_unique = t.b;
-- 连表查询, 使用非唯一键进行关联
-- type=ALL, type=ref
explain select * from test t left join test_explain te on te.`index` = t.b;
-- type=ALL, type=ref
explain select * from test t left join test_explain te on te.`index_joint_1` = t.b;
-- type=ALL, type=ref
explain select * from test t, test_explain te where te.index = t.a;
-- type=ALL, type=ref
explain select * from test t, test_explain te where te.index_joint_1 = t.a;
-- 使用一个值,通过非唯一索引匹配一条或多条记录
-- type=ref, Extra=
explain select * from test_explain where `index_joint_1` = 7;
-- type=ref, Extra=
explain select * from test_explain where `index` = 7;
-- type=ref, Extra=Using index
explain select index_joint_1 from test_explain where `index_joint_1` = 1;
-- type=ref, Extra=Using index
explain select `index` from test_explain where `index` = 1;
-- 使用索引进行范围查询,在主键索引树上过滤数据
-- type=range, Extra=Using where
explain select * from test_explain where id in (1,2);
-- 通过索引进行范围查询,用where过滤索引,发生索引覆盖,不回表
-- type=range, Extra=Using where; Using index
explain select index_unique from test_explain where index_unique<> 1;
-- type=range, Extra=Using where; Using index
explain select `index` from test_explain where `index`<> 1;
-- type=range, Extra=Using where; Using index
explain select index_unique from test_explain where index_unique in (1,2);
-- type=range, Extra=Using where; Using index
explain select index_unique from test_explain where index_unique>1 and index_unique < 4;
-- type=range, Extra=Using where; Using index
explain select index_joint_2 from test_explain where `index_joint_1` in (1,2);
-- type=range, Extra=Using where; Using index
explain select index_joint_1 from test_explain where `index_joint_1` < 4;
-- 通过索引进行范围查询,用where过滤索引,发生回表
-- type=range, Extra=Using index condition
explain select * from test_explain where index_unique in (1,2);
-- type=range, Extra=Using index condition
explain select * from test_explain where index_unique in (1,7);
-- type=range, Extra=Using index condition
explain select * from test_explain where index_unique>1 and index_unique < 4;
-- type=range, Extra=Using index condition
explain select * from test_explain where `index`<> 1;
-- type=range, Extra=Using index condition
explain select * from test_explain where `index` in (1,2);
-- type=range, Extra=Using index condition
explain select * from test_explain where `index_joint_1` in (1,2);
-- type=range, Extra=Using index condition
explain select * from test_explain where `index_joint_1` < 4;
-- 通过索引进行范围查询,用where过滤索引,发生回表,用where过滤数据
-- type=range, Extra=Using index condition; Using where
explain select * from test_explain where index_unique > 1 and `index` < 7;
-- type=range, Extra=Using index condition; Using where
explain select * from test_explain where `index_joint_1` < 4 and no_index_1 > 1;
-- type=range, Extra=Using index condition; Using where
explain select * from test_explain where `index_joint_1` < 4 and `index` > 1;
-- 通过索引进行范围查询,用where过滤索引,发生回表,用where过滤数据,使用索引进行排序
-- type=range, Extra=Using index condition; Using where
explain select * from test_explain where `index_joint_1` < 4 and no_index_1 > 1 order by index_joint_1 asc;
-- 通过索引进行范围查询,用where过滤索引,发生回表,用where过滤数据,使用索引进行逆序排序
-- type=range, Extra=Using index condition; Using where; Backward index scan
explain select * from test_explain where `index_joint_1` < 4 and no_index_1 > 1 order by index_joint_1 desc;
-- 通过索引进行范围查询,用where过滤索引,发生回表,用where过滤数据, 使用外部排序
-- type=range, Extra=Using index condition; Using where; Using filesort
explain select * from test_explain where `index_joint_1` < 4 and no_index_1 > 1 order by index_joint_2 asc;
-- type=range, Extra=Using index condition; Using where; Using filesort
explain select * from test_explain where `index_joint_1` < 4 and no_index_1 > 1 order by `index` asc;
-- 全量扫描索引树,发生索引覆盖,不回表
-- type=index, Extra=Using index
explain select index_unique from test_explain;
-- 全量扫描索引树,在索引树上过滤数据,发生索引覆盖,不回表
-- type=index, Extra=Using where; Using index
explain select index_joint_1 from test_explain where `index_joint_3` = 1;