Linux学习-MySQL之Explain使用
Posted 丢爸
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux学习-MySQL之Explain使用相关的知识,希望对你有一定的参考价值。
####-----------------------------id,table------------------------------------------
#查询的每一行记录都对应着一个单表
mysql> explain select * from s1;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| 1 | SIMPLE | s1 | NULL | ALL | NULL | NULL | NULL | NULL | 9595 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
#s1:驱动表,s2:被驱动表
mysql> EXPLAIN SELECT * FROM s1 INNER JOIN s2;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------------------------+
| 1 | SIMPLE | s1 | NULL | ALL | NULL | NULL | NULL | NULL | 9595 | 100.00 | NULL |
| 1 | SIMPLE | s2 | NULL | ALL | NULL | NULL | NULL | NULL | 9895 | 100.00 | Using join buffer (hash join) |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------------------------+
2 rows in set, 1 warning (0.00 sec)
#在一个大查询的语句中每个SELECT关键字对应一个唯一的ID
mysql> explain select * from s1 where key1='a';
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------+
| 1 | SIMPLE | s1 | NULL | ref | idx_key1 | idx_key1 | 43 | const | 1 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
mysql> explain select * from s1 where key1 in (select key3 from s2);
+----+--------------+-------------+------------+--------+---------------------+---------------------+---------+-----------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+--------------+-------------+------------+--------+---------------------+---------------------+---------+-----------------+------+----------+-------------+
| 1 | SIMPLE | s1 | NULL | ALL | idx_key1 | NULL | NULL | NULL | 9595 | 100.00 | Using where |
| 1 | SIMPLE | <subquery2> | NULL | eq_ref | <auto_distinct_key> | <auto_distinct_key> | 403 | dbtest2.s1.key1 | 1 | 100.00 | Using where |
| 2 | MATERIALIZED | s2 | NULL | index | idx_key3 | idx_key3 | 403 | NULL | 9895 | 100.00 | Using index |
+----+--------------+-------------+------------+--------+---------------------+---------------------+---------+-----------------+------+----------+-------------+
3 rows in set, 1 warning (0.00 sec)
mysql> explain select * from s1 where key1 in (select key1 from s2) or key3='a';
+----+-------------+-------+------------+-------+---------------+----------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+----------+---------+------+------+----------+-------------+
| 1 | PRIMARY | s1 | NULL | ALL | idx_key3 | NULL | NULL | NULL | 9595 | 100.00 | Using where |
| 2 | SUBQUERY | s2 | NULL | index | idx_key1 | idx_key1 | 43 | NULL | 9895 | 100.00 | Using index |
+----+-------------+-------+------------+-------+---------------+----------+---------+------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)
#查询优化器可能对涉及子查询的查询语句进行重写,转变为多表查询
mysql> explain select * from s1 where key1 in (select key2 from s2 where common_field='a');
+----+-------------+-------+------------+--------+---------------+----------+---------+-----------------+------+----------+------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+--------+---------------+----------+---------+-----------------+------+----------+------------------------------------+
| 1 | SIMPLE | s1 | NULL | ALL | idx_key1 | NULL | NULL | NULL | 9595 | 100.00 | Using where |
| 1 | SIMPLE | s2 | NULL | eq_ref | idx_key2 | idx_key2 | 5 | dbtest2.s1.key1 | 1 | 10.00 | Using index condition; Using where |
+----+-------------+-------+------------+--------+---------------+----------+---------+-----------------+------+----------+------------------------------------+
2 rows in set, 2 warnings (0.00 sec)
#UNION去重
mysql> explain select * from s1 union select * from s2;
+----+--------------+------------+------------+------+---------------+------+---------+------+------+----------+-----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+--------------+------------+------------+------+---------------+------+---------+------+------+----------+-----------------+
| 1 | PRIMARY | s1 | NULL | ALL | NULL | NULL | NULL | NULL | 9595 | 100.00 | NULL |
| 2 | UNION | s2 | NULL | ALL | NULL | NULL | NULL | NULL | 9895 | 100.00 | NULL |
| NULL | UNION RESULT | <union1,2> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary |
+----+--------------+------------+------------+------+---------------+------+---------+------+------+----------+-----------------+
3 rows in set, 1 warning (0.00 sec)
mysql> explain select * from s1 union all select * from s2;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| 1 | PRIMARY | s1 | NULL | ALL | NULL | NULL | NULL | NULL | 9595 | 100.00 | NULL |
| 2 | UNION | s2 | NULL | ALL | NULL | NULL | NULL | NULL | 9895 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
2 rows in set, 1 warning (0.00 sec)
###
1.id相同,认为是一组,从上往下顺序执行
2.在所有组中,id值越大,优先级越高,越先执行
3.关注点,id号每个号码,表不一趟独立的查询,一个sql查询趟数越少越好
####-----------------------------id,table------------------------------------------
####-----------------------------select_type------------------------------------------
/*一个大查询语句中包含若干个SELECT关键字,每个SELECT关键字代表一个小的查询语句,而每个SELECT关键字的FROM子句中都可以包含若干张表(连接查询),每一张表都对应着执行计划输出中的一条记录,对于在同一SELECT关键字中的表来说,它们的id相同。
MySQL为每一个SELECT关键字代表的小查询定义了一个select_type属性,我们只要知道某个小查询的select_type属性,就知道这个小查询在整个大查询中扮演了一个什么角色
1.SIMPLE
2.PRIMARY
3.UNION
4.UNION RESULT
5.SUBQUERY
6
*/
#查询语句中不包含‘UNION’或者子查询的查询语句算做是‘SIMPLE’类型
mysql> explain select * from s2;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| 1 | SIMPLE | s2 | NULL | ALL | NULL | NULL | NULL | NULL | 9895 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
#连接查询是‘SIMPLAE’类型
mysql> explain select * from s1 inner join s2;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------------------------+
| 1 | SIMPLE | s1 | NULL | ALL | NULL | NULL | NULL | NULL | 9595 | 100.00 | NULL |
| 1 | SIMPLE | s2 | NULL | ALL | NULL | NULL | NULL | NULL | 9895 | 100.00 | Using join buffer (hash join) |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------------------------+
2 rows in set, 1 warning (0.00 sec)
#包含'UNION'或者'UNION ALL'的大查询,由几个小查询组成,除了最左边的小查询以外,其余小查询的'select_type'的值是'UNION'
#MySQL选择使用临时表来完成‘UNION’查询的去重工作,针对该临时表的查询‘select_type’为'UNION RESULT'
mysql> explain select * from s1 union select * from s2;
+----+--------------+------------+------------+------+---------------+------+---------+------+------+----------+-----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+--------------+------------+------------+------+---------------+------+---------+------+------+----------+-----------------+
| 1 | PRIMARY | s1 | NULL | ALL | NULL | NULL | NULL | NULL | 9595 | 100.00 | NULL |
| 2 | UNION | s2 | NULL | ALL | NULL | NULL | NULL | NULL | 9895 | 100.00 | NULL |
| NULL | UNION RESULT | <union1,2> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary |
+----+--------------+------------+------------+------+---------------+------+---------+------+------+----------+-----------------+
3 rows in set, 1 warning (0.00 sec)
mysql> explain select * from s1 union ALL select * from s2;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| 1 | PRIMARY | s1 | NULL | ALL | NULL | NULL | NULL | NULL | 9595 | 100.00 | NULL |
| 2 | UNION | s2 | NULL | ALL | NULL | NULL | NULL | NULL | 9895 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
2 rows in set, 1 warning (0.00 sec)
#子查询:如果包含子查询的查询语句不能够转为对应的‘semi-join’形式,并且该查询为不相关子查询,该子查询的第一个‘SELECT’关键字代表的那个查询的'select_type'为'SUBQUERY'
mysql> explain select * from s1 where key1 in (select key1 from s2) or key3 ='a';
+----+-------------+-------+------------+-------+---------------+----------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+----------+---------+------+------+----------+-------------+
| 1 | PRIMARY | s1 | NULL | ALL | idx_key3 | NULL | NULL | NULL | 9595 | 100.00 | Using where |
| 2 | SUBQUERY | s2 | NULL | index | idx_key1 | idx_key1 | 43 | NULL | 9895 | 100.00 | Using index |
+----+-------------+-------+------------+-------+---------------+----------+---------+------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)
#子查询:如果包含子查询的查询语句不能够转为对应的‘semi-join’形式,并且该查询为相关子查询,该子查询的第一个‘SELECT’关键字代表的那个查询的'select_type'为'DEPENDENT SUBQUERY',select_type为'DEPENDENT SUBQUERY'的查询可能会被执行多次
mysql> explain select * from s1 where key1 in (select key1 from s2 where s1.key2=s2.key2) or key3='a';
+----+--------------------+-------+------------+--------+-------------------+----------+---------+-----------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+--------------------+-------+------------+--------+-------------------+----------+---------+-----------------+------+----------+-------------+
| 1 | PRIMARY | s1 | NULL | ALL | idx_key3 | NULL | NULL | NULL | 9595 | 100.00 | Using where |
| 2 | DEPENDENT SUBQUERY | s2 | NULL | eq_ref | idx_key2,idx_key1 | idx_key2 | 5 | dbtest2.s1.key2 | 1 | 10.00 | Using where |
+----+--------------------+-------+------------+--------+-------------------+----------+---------+-----------------+------+----------+-------------+
2 rows in set, 2 warnings (0.00 sec)
#在包含‘UNION’或'UNION ALL'的大查询中,如果各个小查询依赖于外层查询的话,那除了最左边的小查询外,其余的小查询的select_type是DEPENDENT UNION
mysql> explain select * from s1 where key1 in (select key1 from s2 where key1='a' union select key1 from s1 where key1='b');
+----+--------------------+------------+------------+------+---------------+-----以上是关于Linux学习-MySQL之Explain使用的主要内容,如果未能解决你的问题,请参考以下文章