一、准备测试环境
1.准备测试表testm和testk:
mysql> create table testk(id int,name varchar(20),tel varchar(20),primary key(id), KEY idx_stu(stu_no),KEY idx_union1 (id,name,tel));
mysql> create table testm(id int,name varchar(20),tel varchar(20),primary key(id),KEY idx_name (name));
2.写入测试数据
mysql> insert into testk values (1,'lin','43454');
mysql> insert into testk values (3,'lin','4344');
mysql> insert into testm values (1,'lin','43454');
mysql> insert into testm values (3,'lin','4344');
二、执行计划基础信息解析
[explain|desc] select …通过该命令查看执行计划
注:desc在mysql里适用,在drds里不适用
1.执行计划查看
mysql> explain select name from testk where id=1;
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| 1 | SIMPLE | testk | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | NULL |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.01 sec)
2.执行计划字段解析
1)id------查询语句标识
- id 相同时执行顺序从上至下;
- id 不同时 ,序号越大越早执行。
explain select count(t.id) from t_user t where t.name in(select a.name from t_user a where a.id<2000) or t.name in (select b.name from t_user b where id<-1);
例子的执行计划如上,可以看到3号<-1的子查询最先进行,2号<1999的子查询其次,最后进行半连接查询。
2)select_type------查询语句的类型,区别普通查询和联合查询、子查询之类的复杂查询
- SIMPLE:查询中不包含子查询或者UNION
3)table----当前表名
4)partitions-----显示查询将访问的分区(如果查询基于分区表)
5)type-----当前表内访问方式
(性能排序:const(system) > eq_ref > ref > range > index > ALL)
- const,system:
单表中最多有一个匹配行,查询速度高,例如根据主键或唯一索引查询;
system是const类型的特例,当查询的表只有一行的情况下, 使用system。
如:SELECT * FROM tbl_name WHERE primary_key=1。 - eq_ref:
唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描。
const和eq_ref区别:
const用于单表主键查询,eq_ref用于关联主键查询。
eg.关联主键查询:
注意区分select *的情况(select *涉及到回表,所以谨慎使用):
- ref:
使用非唯一索引或非唯一索引前缀进行的查找
- range:
范围检索
- index:
会扫描索引树,仅比ALL快些。
6)possible_keys----可能使用到的索引
7)key----经过优化器评估最终使用的索引
8)key_len -----使用的索引键的索引列的长度,有助于辅助分析复合索引的情况下启用了哪几个索引列
- 通常情况下key_len等于索引列的字节长度。如Tinyint为1字节,int为4字节;
- 若该列允许null,则key_len加上1byte;
- 若该列为变长类型,则key_len加上2byte。
eg1.分别通过主键和可为空索引(int类型)进行查询,可以看到:
① 通过主键id查询,key_len=4byte(int的长度);
② 通过可为空索引stu_no进行查询,key_len=5byte(null字段需要+1byte)。
eg2.通过可为空索引(varchar类型)进行查询:
① 字符集为UTF8,name字段为故长度为varchar(20),故需要*3;(UTF8占3个字节,GBK占用2个字节,Latin占用1个字节)
② 允许为NULL,需要+1;
③ 变长类型,需要+2。
故key_len为63
eg3.复合索引查询:
待补充
9)ref-----是通过变量还是某个表的字段过滤的
10)rows-----要得到最终记录索要扫描经过的记录数
11)filtered-----表示存储引擎返回的数据在server层过滤后,剩下多少满足查询的记录数量的比例,注意是百分比,不是具体记录数。
12)Extra
详见执行计划之Extra详解