EXPLAIN为语句中使用的每个表返回一行信息 SELECT。它按照 MySQL 在处理语句时读取它们的顺序列出输出中的表。这意味着 MySQL 从第一个表中读取一行,然后在第二个表中找到匹配的行,然后在第三个表中,依此类推。当所有的表都被处理完后,MySQL 将选择的列输出,并在表列表中回溯,直到找到一个有更多匹配行的表。从此表中读取下一行,然后继续处理下一个表
create table student
(
student_id bigint auto_increment comment '学生id'
primary key,
name varchar(20) null comment '学生姓名',
age int null comment '年龄'
)
comment '学生表';
create table score
(
score_id bigint auto_increment comment '分数id'
primary key,
student_id bigint not null comment '学生id',
subject varchar(20) null comment '科目',
score decimal(5, 2) null comment '分数'
)
comment '学生成绩表';
create index idx_student_id
on score (student_id);
create index idx_subject
on score (subject);
insert into md_test.student (student_id, name, age)
values (1, '小明', 18),
(2, '张三', 19),
(3, '李四', 19),
(4, '王二', 17),
(5, '孙悟空', 17),
(6, '猪八戒', 20);
insert into md_test.score (score_id, student_id, subject, score)
values (1, 1, '语文', 90.00),
(2, 1, '数学', 98.00),
(3, 2, '语文', 97.00),
(4, 2, '数学', 87.00),
(5, 3, '语文', 78.00),
(6, 3, '数学', 88.00),
(7, 4, '语文', 99.00),
(8, 4, '数学', 100.00),
(9, 5, '语文', 96.00),
(10, 5, '数学', 78.00),
(11, 6, '语文', 87.00),
(12, 6, '数学', 88.00);
explain
select * from student;
explain
select * from student limit 1;
explain
select (select st.name from student st where st.student_id = sc.student_id) as student_name, sc.score
from score sc;
explain
select (select st.name from student st where st.student_id = sc.student_id) as student_name, sc.score
from score sc;
explain
select * from student s1 where s1.student_id=1
union
select * from student s2 where s2.student_id=4;
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
explain
select *
from student s1
where s1.student_id = 1;
explain
select (select st.name from student st where st.student_id = sc.student_id) as student_name, sc.score
from (select * from score s where s.score > 80) sc;
explain
select * from score sc where sc.student_id=3;
ref_or_null
这种连接类型类似于 ref,但 MySQL 对包含值的行进行了额外的搜索NULL。这种连接类型优化最常用于解析子查询
index_merge
此连接类型表示使用索引合并优化
range
仅检索给定范围内的行,使用索引来选择行。key 输出行中的列指示使用了哪个索引。包含key_len使用过的最长的密钥部分。该ref列 NULL适用于此类型。
range=可以在使用, <>, >, >=, , <, <=, IS NULL, <=>, BETWEEN, LIKE或 运算符将键列与常量进行比较时使用 IN()
explain
select *
from student
where student_id>2 and student_id<6;
show index from table_name
这一列显示了mysql在索引里使用的字节数,通过这个值可以算出具体使用了索引中的哪些列
该ref列显示将哪些列或常量与列中指定的索引进行比较 key以从表中选择行
该rows列表示查询扫描的行数
对于InnoDB表格,此数字是一个估计值,可能并不总是准确的
查询的附加信息
distinct
一旦mysql找到了与行相联合匹配的行,就不再搜索了
Using index
select语句中使用覆盖索引,以避免回表查询(当查询仅使用属于单个索引的列时,可以使用此策略)
explain
select student_id
from student
where student_id=2;
explain
select *
from student
where student_id>2;