explain和desc命令的效果相同,命令格式如下:
mysql> explain SELECT s.id sid, s.name sname , t.id tid ,t.name tname FROM student s LEFT JOIN teacher t ON s.name = t.name;
+----+-------------+-------+-------+---------------+------+---------+------+------+----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+------+---------+------+------+----------------------------------------------------+
| 1 | SIMPLE | s | index | NULL | name | 768 | NULL | 3 | Using index |
| 1 | SIMPLE | t | ALL | NULL | NULL | NULL | NULL | 10 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+-------+---------------+------+---------+------+------+----------------------------------------------------+
2 rows in setmysql> desc SELECT s.id sid, s.name sname , t.id tid ,t.name tname FROM student s LEFT JOIN teacher t ON s.name = t.name;
+----+-------------+-------+-------+---------------+------+---------+------+------+----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+------+---------+------+------+----------------------------------------------------+
| 1 | SIMPLE | s | index | NULL | name | 768 | NULL | 3 | Using index |
| 1 | SIMPLE | t | ALL | NULL | NULL | NULL | NULL | 10 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+-------+---------------+------+---------+------+------+----------------------------------------------------+
2 rows in set
mysql> explain student;
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | MUL | NULL | |
| age | int(11) | YES | | NULL | |
+-------+--------------+------+-----+---------+----------------+
3 rows in setmysql> desc student;
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | MUL | NULL | |
| age | int(11) | YES | | NULL | |
+-------+--------------+------+-----+---------+----------------+
3 rows in set
用于数据表:
mysql> desc student;
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | MUL | NULL | |
| age | int(11) | YES | | NULL | |
+-------+--------------+------+-----+---------+----------------+Field:表中的字段名
Type:字段对应的类型
Null:可否为空
Key:键类型,主键、索引键。。。
Default:默认值
Extra:其他信息
用于sql:
mysql> explain SELECT s.id sid, s.name sname , t.id tid ,t.name tname FROM student s LEFT JOIN teacher t ON s.name = t.name;
+----+-------------+-------+-------+---------------+------+---------+------+------+----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+------+---------+------+------+----------------------------------------------------+
| 1 | SIMPLE | s | index | NULL | name | 768 | NULL | 3 | Using index |
| 1 | SIMPLE | t | ALL | NULL | NULL | NULL | NULL | 10 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+-------+---------------+------+---------+------+------+----------------------------------------------------+id:查询的序列号select_type:查询的类型,普通查询、联合查询、子查询等table:输出行所引用的表名type:联合查询的访问类型,此属性比较重要possible_keys:表示能使用哪个索引在该表中找到行key:实际使用的索引键,如果没有索引被选择,键是NULLkey_len:实际使用的键长度ref:显示哪个字段或常数与key一起被使用进行查询rows:表示要遍历多少数据才能找到满足条件的数据,在innodb上是不准确的extra:附加信息
着重解释:
select_type字段:
SIMPLE | 简单查询,不适用UNION或子查询 |
PRIMARY | 最外层的SELECT |
UNION | UNION中的第二个或后面的SELECT语句 |
DEPENDENT UNION | UNION中的第二个或后面的SELECT语句,取决于外面的查询 |
UNION RESULT | UNION的结果 |
SUBQUERY | 子查询中的第一个SELECT |
DEPENDENT SUBQUERY | 子查询中的第一个SELECT,取决于外面的查询 |
DERIVED | FROM子句的子查询 |
type字段:
SYSTEM | 表中只有一行记录 |
CONST | 表中最多只有一行匹配的记录,他在查询一开始就会被读取出来,被作为一个恒定值 |
EQ_REF | 表中会有一行记录被读取出来和以前一个表中读取出来的记录做联合,这是最好的连接类型,他用在索引所有字段都用于做连接并且这个索引是primary key或unique类型 |
REF | 表中所有符合检索值的记录都会被取出来和从上一个表中取出来的记录做联合,用于连接程序无法根据键值只取得一条记录的情况 |
REF_OR_NULL | 和REF类似,在检索的时候会搜索NULL值的记录,经常用于子查询 |
UNIQUE_SUBQUERY | 带in的子查询来代替ref |
INDEX_SUBQUERY | 用子查询来代替in |
RANGE | 只有在给定范围的记录才会被取出来,利用索引来取得一条记录,key字段表示使用了那个索引 |
INDEX | 只扫描所引树 |
ALL | 对表做全部扫描,应尽量避免 |
extra字段:
DISTINCT | 找到当前记录的匹配联合结果的第一条记录之后,不再搜索其他记录 |
NOT EXISTS | 做一个left join优化,在当前表中找到和前一条记录符合left join条件后,就不再搜索更多的记录 |
RANGE CHECKED FOR EACH RECORD (INDEX MAP:#) | 没有找到合适的可用的索引,取代的办法是:对于前一个表的每一个行连接,它会做一个校验以决定该使用那个索引,并且使用这个索引来从表中取得记录。 |
USING FILESORT | 需要额外做一遍排序操作,以拍好的顺序取得记录,应尽量避免 |
USING INDEX | 直接从索引树中的信息取得记录,不再去扫描实际的记录 |
USING TEMPORARY | 创建临时表存储结果以完成查询,通常发生在查询时包含了group by和order by子句,应尽量避免 |
USING WHERE | where子句将用来限制哪些记录匹配了下一个表或者发送到客户端 |
可通过上述对表和sql分析来进行对应的修改,以使得性能达到最优