当前位置: 金沙澳门官网网址cow > 智能科技 > 正文

金沙澳门官网网址cow详细介绍,explain用法和结果

时间:2019-11-22 13:40来源:智能科技
1.1、ctrl+c。在当前session中,手动执行ctrl+c。无影响,并且会自动删除产生的临时文件。 mysql explain select * from t_order where user_id in (select user_id from t_order where order_id10);  +----+-

1.1、ctrl+c。在当前session中,手动执行ctrl+c。无影响,并且会自动删除产生的临时文件。

  1. mysql> explain select * from t_order where user_id in (select user_id from t_order where order_id>10); 
  2. +----+--------------------+---------+----------------+-----------------+---------+---------+------+--------+--------------------------+ 
  3. | id | select_type        | table   | type           | possible_keys   | key     | key_len | ref  | rows   | Extra                    | 
  4. +----+--------------------+---------+----------------+-----------------+---------+---------+------+--------+--------------------------+ 
  5. |  1 | PRIMARY            | t_order | ALL            | NULL            | NULL    | NULL    | NULL | 100649 | Using where              | 
  6. |  2 | DEPENDENT SUBQUERY | t_order | index_subquery | PRIMARY,user_id | user_id | 5       | func |  50324 | Using index; Using where | 
  7. +----+--------------------+---------+----------------+-----------------+---------+---------+------+--------+--------------------------+ 
  8. 2 rows in set (0.00 sec) 

Mysql Explain 详细介绍,mysqlexplain

Mysql Explain 这里做一个资料的全面整理。

一.语法

explain < table_name >

例如: explain select * from t3 where id=3952602;

二.explain输出解释

+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+
| id | select_type | table | type  | possible_keys     | key     | key_len | ref   | rows | Extra |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+

1.id

  我的理解是SQL执行的顺利的标识,SQL从大到小的执行.

例如:

mysql> explain select * from (select * from ( select * from t3 where id=3952602) a) b;
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
| id | select_type | table      | type   | possible_keys     | key     | key_len | ref  | rows | Extra |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
|  1 | PRIMARY     | <derived2> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | <derived3> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  3 | DERIVED     | t3         | const  | PRIMARY,idx_t3_id | PRIMARY | 4       |      |    1 |       |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+

很显然这条SQL是从里向外的执行,就是从id=3 向上执行.

  1. select_type

就是select类型,可以有以下

(1) SIMPLE

简单SELECT(不使用UNION或子查询等) 例如:

mysql> explain select * from t3 where id=3952602;

+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+
| id | select_type | table | type  | possible_keys     | key     | key_len | ref   | rows | Extra |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 |       |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+

(2). PRIMARY

我的理解是最外层的select.例如:

mysql> explain select * from (select * from t3 where id=3952602) a ;

+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
| id | select_type | table      | type   | possible_keys     | key     | key_len | ref  | rows | Extra |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
|  1 | PRIMARY     | <derived2> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | t3         | const  | PRIMARY,idx_t3_id | PRIMARY | 4       |      |    1 |       |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+

(3).UNION

UNION中的第二个或后面的SELECT语句.例如

mysql> explain select * from t3 where id=3952602 union all select * from t3 ;

+----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+
| id | select_type  | table      | type  | possible_keys     | key     | key_len | ref   | rows | Extra |
+----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+
|  1 | PRIMARY      | t3         | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 |       |
|  2 | UNION        | t3         | ALL   | NULL              | NULL    | NULL    | NULL  | 1000 |       |
|NULL | UNION RESULT | <union1,2> | ALL   | NULL              | NULL    | NULL    | NULL  | NULL |       |
+----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+

(4).DEPENDENT UNION

UNION中的第二个或后面的SELECT语句,取决于外面的查询

mysql> explain select * from t3 where id in (select id from t3 where id=3952602 union all select id from t3)  ;

+----+--------------------+------------+--------+-------------------+---------+---------+-------+------+--------------------------+
| id | select_type        | table      | type   | possible_keys     | key     | key_len | ref   | rows | Extra                    |
+----+--------------------+------------+--------+-------------------+---------+---------+-------+------+--------------------------+
|  1 | PRIMARY            | t3         | ALL    | NULL              | NULL    | NULL    | NULL  | 1000 | Using where              |
|  2 | DEPENDENT SUBQUERY | t3         | const  | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 | Using index              |
|  3 | DEPENDENT UNION    | t3         | eq_ref | PRIMARY,idx_t3_id | PRIMARY | 4       | func  |    1 | Using where; Using index |
|NULL | UNION RESULT       | <union2,3> | ALL    | NULL              | NULL    | NULL    | NULL  | NULL |                          |
+----+--------------------+------------+--------+-------------------+---------+---------+-------+------+--------------------------+

(4).UNION RESULT

UNION的结果。

mysql> explain select * from t3 where id=3952602 union all select * from t3 ;

+----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+
| id | select_type  | table      | type  | possible_keys     | key     | key_len | ref   | rows | Extra |
+----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+
|  1 | PRIMARY      | t3         | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 |       |
|  2 | UNION        | t3         | ALL   | NULL              | NULL    | NULL    | NULL  | 1000 |       |
|NULL | UNION RESULT | <union1,2> | ALL   | NULL              | NULL    | NULL    | NULL  | NULL |       |
+----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+

(5).SUBQUERY

子查询中的第一个SELECT.

mysql> explain select * from t3 where id = (select id from t3 where id=3952602 )  ;

+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------------+
| id | select_type | table | type  | possible_keys     | key     | key_len | ref   | rows | Extra       |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------------+
|  1 | PRIMARY     | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 |             |
|  2 | SUBQUERY    | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4       |       |    1 | Using index |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------------+

(6).  DEPENDENT SUBQUERY

子查询中的第一个SELECT,取决于外面的查询

mysql> explain select id from t3 where id in (select id from t3 where id=3952602 )  ;

+----+--------------------+-------+-------+-------------------+---------+---------+-------+------+--------------------------+
| id | select_type        | table | type  | possible_keys     | key     | key_len | ref   | rows | Extra                    |
+----+--------------------+-------+-------+-------------------+---------+---------+-------+------+--------------------------+
|  1 | PRIMARY            | t3    | index | NULL              | PRIMARY | 4       | NULL  | 1000 | Using where; Using index |
|  2 | DEPENDENT SUBQUERY | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 | Using index              |
+----+--------------------+-------+-------+-------------------+---------+---------+-------+------+--------------------------+

7).DERIVED

派生表的SELECT(FROM子句的子查询)

mysql> explain select * from (select * from t3 where id=3952602) a ;

+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
| id | select_type | table      | type   | possible_keys     | key     | key_len | ref  | rows | Extra |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
|  1 | PRIMARY     | <derived2> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | t3         | const  | PRIMARY,idx_t3_id | PRIMARY | 4       |      |    1 |       |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+

3.table

显示这一行的数据是关于哪张表的.

有时不是真实的表名字,看到的是derivedx(x是个数字,我的理解是第几步执行的结果)

mysql> explain select * from (select * from ( select * from t3 where id=3952602) a) b;

+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
| id | select_type | table      | type   | possible_keys     | key     | key_len | ref  | rows | Extra |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
|  1 | PRIMARY     | <derived2> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | <derived3> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  3 | DERIVED     | t3         | const  | PRIMARY,idx_t3_id | PRIMARY | 4       |      |    1 |       |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+

4.type

这列很重要,显示了连接使用了哪种类别,有无使用索引.

从最好到最差的连接类型为const、eq_reg、ref、range、indexhe和ALL

(1).system

这是const联接类型的一个特例。表仅有一行满足条件.如下(t3表上的id是 primary key)

mysql> explain select * from (select * from t3 where id=3952602) a ;

+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
| id | select_type | table      | type   | possible_keys     | key     | key_len | ref  | rows | Extra |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
|  1 | PRIMARY     | <derived2> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | t3         | const  | PRIMARY,idx_t3_id | PRIMARY | 4       |      |    1 |       |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+

(2).const

表最多有一个匹配行,它将在查询开始时被读取。因为仅有一行,在这行的列值可被优化器剩余部分认为是常数。const表很快,因为它们只读取一次!

const用于用常数值比较PRIMARY KEY或UNIQUE索引的所有部分时。在下面的查询中,tbl_name可以用于const表:

SELECT * from tbl_name WHERE primary_key=1;
SELECT * from tbl_name WHERE primary_key_part1=1和 primary_key_part2=2;

例如:

mysql> explain select * from t3 where id=3952602;

+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+
| id | select_type | table | type  | possible_keys     | key     | key_len | ref   | rows | Extra |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 |       |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+

(3). eq_ref

对于每个来自于前面的表的行组合,从该表中读取一行。这可能是最好的联接类型,除了const类型。它用在一个索引的所有部分被联接使用并且索引是UNIQUE或PRIMARY KEY。

eq_ref可以用于使用= 操作符比较的带索引的列。比较值可以为常量或一个使用在该表前面所读取的表的列的表达式。

在下面的例子中,MySQL可以使用eq_ref联接来处理ref_tables:

SELECT * FROM ref_table,other_table
 WHERE ref_table.key_column=other_table.column;


SELECT * FROM ref_table,other_table
 WHERE ref_table.key_column_part1=other_table.column
  AND ref_table.key_column_part2=1;

例如

mysql> create unique index  idx_t3_id on t3(id) ;
Query OK, 1000 rows affected (0.03 sec)
Records: 1000  Duplicates: 0  Warnings: 0

mysql> explain select * from t3,t4 where t3.id=t4.accountid;

+----+-------------+-------+--------+-------------------+-----------+---------+----------------------+------+-------+
| id | select_type | table | type   | possible_keys     | key       | key_len | ref                  | rows | Extra |
+----+-------------+-------+--------+-------------------+-----------+---------+----------------------+------+-------+
|  1 | SIMPLE      | t4    | ALL    | NULL              | NULL      | NULL    | NULL                 | 1000 |       |
|  1 | SIMPLE      | t3    | eq_ref | PRIMARY,idx_t3_id | idx_t3_id | 4       | dbatest.t4.accountid |    1 |       |
+----+-------------+-------+--------+-------------------+-----------+---------+----------------------+------+-------+

(4).ref

对于每个来自于前面的表的行组合,所有有匹配索引值的行将从这张表中读取。如果联接只使用键的最左边的前缀,或如果键不是UNIQUE或PRIMARY KEY(换句话说,如果联接不能基于关键字选择单个行的话),则使用ref。如果使用的键仅仅匹配少量行,该联接类型是不错的。
ref可以用于使用=或<=>操作符的带索引的列。

在下面的例子中,MySQL可以使用ref联接来处理ref_tables:

SELECT * FROM ref_table WHERE key_column=expr;

SELECT * FROM ref_table,other_table
 WHERE ref_table.key_column=other_table.column;

SELECT * FROM ref_table,other_table
 WHERE ref_table.key_column_part1=other_table.column
  AND ref_table.key_column_part2=1;

例如:

mysql> drop index idx_t3_id on t3;
Query OK, 1000 rows affected (0.03 sec)
Records: 1000 Duplicates: 0 Warnings: 0

mysql> create index idx_t3_id on t3(id) ;
Query OK, 1000 rows affected (0.04 sec)
Records: 1000 Duplicates: 0 Warnings: 0

mysql> explain select * from t3,t4 where t3.id=t4.accountid;

+----+-------------+-------+------+-------------------+-----------+---------+----------------------+------+-------+
| id | select_type | table | type | possible_keys     | key       | key_len | ref                  | rows | Extra |
+----+-------------+-------+------+-------------------+-----------+---------+----------------------+------+-------+
|  1 | SIMPLE      | t4    | ALL  | NULL              | NULL      | NULL    | NULL                 | 1000 |       |
|  1 | SIMPLE      | t3    | ref  | PRIMARY,idx_t3_id | idx_t3_id | 4       | dbatest.t4.accountid |    1 |       |
+----+-------------+-------+------+-------------------+-----------+---------+----------------------+------+-------+

2 rows in set (0.00 sec)

(5).  ref_or_null

该联接类型如同ref,但是添加了MySQL可以专门搜索包含NULL值的行。在解决子查询中经常使用该联接类型的优化。

在下面的例子中,MySQL可以使用ref_or_null联接来处理ref_tables:

SELECT * FROM ref_table
WHERE key_column=expr OR key_column IS NULL;

(6). index_merge

该联接类型表示使用了索引合并优化方法。在这种情况下,key列包含了使用的索引的清单,key_len包含了使用的索引的最长的关键元素。

例如:

mysql> explain select * from t4 where id=3952602 or accountid=31754306 ;

+----+-------------+-------+-------------+----------------------------+----------------------------+---------+------+------+------------------------------------------------------+
| id | select_type | table | type        | possible_keys              | key                        | key_len | ref  | rows | Extra                                                |
+----+-------------+-------+-------------+----------------------------+----------------------------+---------+------+------+------------------------------------------------------+
|  1 | SIMPLE      | t4    | index_merge | idx_t4_id,idx_t4_accountid | idx_t4_id,idx_t4_accountid | 4,4     | NULL |    2 | Using union(idx_t4_id,idx_t4_accountid); Using where |
+----+-------------+-------+-------------+----------------------------+----------------------------+---------+------+------+------------------------------------------------------+

1 row in set (0.00 sec)

(7). unique_subquery

该类型替换了下面形式的IN子查询的ref:

value IN (SELECT primary_key FROM single_table WHERE some_expr)

unique_subquery是一个索引查找函数,可以完全替换子查询,效率更高。

(8).index_subquery

该联接类型类似于unique_subquery。可以替换IN子查询,但只适合下列形式的子查询中的非唯一索引:

value IN (SELECT key_column FROM single_table WHERE some_expr)

(9).range

只检索给定范围的行,使用一个索引来选择行。key列显示使用了哪个索引。key_len包含所使用索引的最长关键元素。在该类型中ref列为NULL。

当使用=、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN或者IN操作符,用常量比较关键字列时,可以使用range

mysql> explain select * from t3 where id=3952602 or id=3952603 ;

+----+-------------+-------+-------+-------------------+-----------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys     | key       | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+-------------------+-----------+---------+------+------+-------------+
|  1 | SIMPLE      | t3    | range | PRIMARY,idx_t3_id | idx_t3_id | 4       | NULL |    2 | Using where |
+----+-------------+-------+-------+-------------------+-----------+---------+------+------+-------------+

1 row in set (0.02 sec)

(10).index

该联接类型与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。

当查询只使用作为单索引一部分的列时,MySQL可以使用该联接类型。

(11). ALL

对于每个来自于先前的表的行组合,进行完整的表扫描。如果表是第一个没标记const的表,这通常不好,并且通常在它情况下很差。通常可以增加更多的索引而不要使用ALL,使得行能基于前面的表中的常数值或列值被检索出。

5.possible_keys

possible_keys列指出MySQL能使用哪个索引在该表中找到行。注意,该列完全独立于EXPLAIN输出所示的表的次序。这意味着在possible_keys中的某些键实际上不能按生成的表次序使用。

如果该列是NULL,则没有相关的索引。在这种情况下,可以通过检查WHERE子句看是否它引用某些列或适合索引的列来提高你的查询性能。如果是这样,创造一个适当的索引并且再次用EXPLAIN检查查询

  1. key

key列显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

7.key_len

key_len列显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。
使用的索引的长度。在不损失精确性的情况下,长度越短越好

  1. ref

ref列显示使用哪个列或常数与key一起从表中选择行。

  1. rows

rows列显示MySQL认为它执行查询时必须检查的行数。

  1. Extra

该列包含MySQL解决查询的详细信息,下面详细.

(1).Distinct

一旦MYSQL找到了与行相联合匹配的行,就不再搜索了

(2).Not exists

MYSQL优化了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行,

就不再搜索了

(3).Range checked for each

Record(index map:#)

没有找到理想的索引,因此对于从前面表中来的每一个行组合,MYSQL检查使用哪个索引,并用它来从表中返回行。这是使用索引的最慢的连接之一

(4).Using filesort

看到这个的时候,查询就需要优化了。MYSQL需要进行额外的步骤来发现如何对返回的行排序。它根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行

(5).Using index

列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候

(6).Using temporary

看到这个的时候,查询需要优化了。这里,MYSQL需要创建一个临时表来存储结果,这通常发生在对不同的列集进行ORDER BY上,而不是GROUP BY上

(7).Using where

使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。如果不想返回表中的全部行,并且连接类型ALL或index,这就会发生,或者是查询有问题

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

Explain 详细介绍,mysqlexplain Mysql Explain 这里做一个资料的全面整理。 一.语法 explain table_name 例如: explain select * from t3 where id=3952602; 二...

1、添加/删除列,采用copy的方式

  1. mysql> explain select * from t_order where order_id in (select order_id from t_order where order_id=100 union select order_id from t_order where order_id=200); 
  2. +----+--------------------+------------+-------+---------------+---------+---------+-------+--------+-------------+ 
  3. | id | select_type        | table      | type  | possible_keys | key     | key_len | ref   | rows   | Extra       | 
  4. +----+--------------------+------------+-------+---------------+---------+---------+-------+--------+-------------+ 
  5. |  1 | PRIMARY            | t_order    | ALL   | NULL          | NULL    | NULL    | NULL  | 100453 | Using where | 
  6. |  2 | DEPENDENT SUBQUERY | t_order    | const | PRIMARY       | PRIMARY | 4       | const |      1 | Using index | 
  7. |  3 | DEPENDENT UNION    | t_order    | const | PRIMARY       | PRIMARY | 4       | const |      1 | Using index | 
  8. | NULL | UNION RESULT       | <union2,3> | ALL   | NULL          | NULL    | NULL    | NULL  |   NULL |             | 
  9. +----+--------------------+------------+-------+---------------+---------+---------+-------+--------+-------------+ 
  10. 4 rows in set (0.03 sec) 

2018年8月9日,周四

2.DEPENDENT UNION与DEPENDENT SUBQUERY:

2.1、ctrl+c,同1.1

分类: Mysql/postgreSQL

责任编辑:

  1. mysql> explain select * from t_order where order_id=100 or user_id=10; 
  2. +----+-------------+---------+-------------+-----------------+-----------------+---------+------+------+-------------------------------------------+ 
  3. | id | select_type | table   | type        | possible_keys   | key             | key_len | ref  | rows | Extra                                     | 
  4. +----+-------------+---------+-------------+-----------------+-----------------+---------+------+------+-------------------------------------------+ 
  5. |  1 | SIMPLE      | t_order | index_merge | PRIMARY,user_id | PRIMARY,user_id | 4,5     | NULL |    2 | Using union(PRIMARY,user_id); Using where | 
  6. +----+-------------+---------+-------------+-----------------+-----------------+---------+------+------+-------------------------------------------+ 
  7. 1 row in set (0.09 sec) 

Redis集群的slot迁移是如何实现的?

有必要解释一下这个长长的表格里每一列的含义:

在迁移过程中如果有数据访问,如果数据没迁移到目标节点,那么直接返回结果,如果迁移到目标节点,那么给客户端返回ASK重定向。

发生这种情况一般都是需要进行优化的。mysql需要创建一张临时表用来处理此类查询。

所以,unique_checks=0并不是允许唯一约束失效,而是再批量导数据时不再逐行检查唯一性。

  1. mysql> explain extended select * from t_order; 
  2. +----+-------------+---------+------+---------------+------+---------+------+--------+----------+-------+ 
  3. | id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra | 
  4. +----+-------------+---------+------+---------------+------+---------+------+--------+----------+-------+ 
  5. |  1 | SIMPLE      | t_order | ALL  | NULL          | NULL | NULL    | NULL | 100453 |   100.00 |       | 
  6. +----+-------------+---------+------+---------------+------+---------+------+--------+----------+-------+ 
  7. 1 row in set, 1 warning (0.00 sec) 

MySQL的表中有唯一索引,设置unique_checks为0时,还能否写入重复值?

  1. mysql> explain select * from t_order where order_id=100 union select * from t_order where order_id=200; 
  2. +----+--------------+------------+-------+---------------+---------+---------+-------+------+-------+ 
  3. | id | select_type  | table      | type  | possible_keys | key     | key_len | ref   | rows | Extra | 
  4. +----+--------------+------------+-------+---------------+---------+---------+-------+------+-------+ 
  5. |  1 | PRIMARY      | t_order    | const | PRIMARY       | PRIMARY | 4       | const |    1 |       | 
  6. |  2 | UNION        | t_order    | const | PRIMARY       | PRIMARY | 4       | const |    1 |       | 
  7. | NULL | UNION RESULT | <union1,2> | ALL   | NULL          | NULL    | NULL    | NULL  | NULL |       | 
  8. +----+--------------+------------+-------+---------------+---------+---------+-------+------+-------+ 
  9. 3 rows in set (0.34 sec) 

2018年8月27日,周一

一.select_type的说明

1.2、kill -9。在执行ddl的时候,服务器发生意外宕机或者手动执行kill -9。待MySQL启动后,则会自动执行InnoDB Recovered流程。并且不会删除产生的临时文件,需要手工处理。

  1. mysql> explain select * from t_order where order_id=100 or user_id>10; 
  2. +----+-------------+---------+-------------+-----------------+-----------------+---------+------+------+------------------------------------------------+ 
  3. | id | select_type | table   | type        | possible_keys   | key             | key_len | ref  | rows | Extra                                          | 
  4. +----+-------------+---------+-------------+-----------------+-----------------+---------+------+------+------------------------------------------------+ 
  5. |  1 | SIMPLE      | t_order | index_merge | PRIMARY,user_id | user_id,PRIMARY | 5,4     | NULL |    2 | Using sort_union(user_id,PRIMARY); Using where | 
  6. +----+-------------+---------+-------------+-----------------+-----------------+---------+------+------+------------------------------------------------+ 
  7. 1 row in set (0.00 sec) 

《叶问》是知数堂新设计的互动栏目,不定期给大家提供技术知识小贴士,形式不限,或提问、或讨论均可,并在当天发布答案,让大家轻轻松松利用碎片时间就可以学到最实用的知识点。

6.unique_subquery

下面是两个SQL的执行计划:

8.range

这种情况下,查询条件 WHERE type != 1,是有可能也可以走索引的。

当有where子句时,extra都会有说明。

在开始执行alter table的过程中,在没有结束的时候,并不会写入到binglog文件中。返回搜狐,查看更多

完整的扫描全表,最慢的联接类型,尽可能的避免。

2.2、kill -9。不会删除临时文件,也不会执行InnoDB Recovered流程并且报错 Operating system error number 2 in a file operation ....OS error: 71

6.Using temporary

2、添加/删除索引,采用INPLACE方式

4.Using filesort

答:迁移源slot设置为migrating 状态,迁移目标slot设置为importing状态。

3.Range checked for each record

在内部用dump & restore命令,把数据迁移到目标节点,迁移结束之后,移除migrating和importing状态。

  1. mysql> explain select * from t_order a,t_order_ext b where a.order_id=b.order_id; 
  2. +----+-------------+-------+--------+---------------+---------+---------+-----------------+------+-------------+ 
  3. | id | select_type | table | type   | possible_keys | key     | key_len | ref             | rows | Extra       | 
  4. +----+-------------+-------+--------+---------------+---------+---------+-----------------+------+-------------+ 
  5. |  1 | SIMPLE      | b     | ALL    | order_id      | NULL    | NULL    | NULL            |    1 |             | 
  6. |  1 | SIMPLE      | a     | eq_ref | PRIMARY       | PRIMARY | 4       | test.b.order_id |    1 | Using where | 
  7. +----+-------------+-------+--------+---------------+---------+---------+-----------------+------+-------------+ 
  8. 2 rows in set (0.00 sec) 

答:通常情况下,这个说法是正确的。当然,也有特殊情况,话不能说绝对了。

3.ref

你认可他的说法吗?

先看一个例子:

某人曰,在数据检索的条件中使用!=操作符时,存储引擎会放弃使用索引。 理由:因为检索的范围不能确定,所以使用索引效率不高,会被引擎自动改为全表扫描。

1.UNION:

叶问

子查询中的第一个select其select_type为SUBQUERY。

有一个测试表共80万条数据,其中type列只有1、2两个值,分别占比97%和3%。

重点是第二种用法,需要深入的了解。

2018年8月17日,周一

经常出现在使用一张表中的多个索引时。mysql会将多个索引合并在一起,如下例:

其次,设置unique_checks=0的作用在于,批量导入数据(例如load data)时,在确保导入数据中无重复值时,无需再次检查其唯一性,加快导入速度。

  1. mysql> explain select count(*) from t_order; 
  2. +----+-------------+---------+-------+---------------+---------+---------+------+--------+-------------+ 
  3. | id | select_type | table   | type  | possible_keys | key     | key_len | ref  | rows   | Extra       | 
  4. +----+-------------+---------+-------+---------------+---------+---------+------+--------+-------------+ 
  5. |  1 | SIMPLE      | t_order | index | NULL          | user_id | 5       | NULL | 100649 | Using index | 
  6. +----+-------------+---------+-------+---------------+---------+---------+------+--------+-------------+ 
  7. 1 row in set (0.00 sec) 

2018年8月15日,周六

9.index

mysql> desc select * from t1 where type = 1G ************ 1. row ************ id: 1 select_type: SIMPLE table: t1 partitions: NULL type: ref possible_keys: type key: type key_len: 4 ref: const rows: 399731 filtered: 100.00 Extra: NULL mysql> desc select * from t1 where type != 1G ************ 1. row ************ id: 1 select_type: SIMPLE table: t1 partitions: NULL type: ref possible_keys: type key: type key_len: 4 ref: const rows: 10182 filtered: 100.00 Extra: NULL type数据分布 mysql> select type, count(*) as cnt from t1 group by type order by cnt; +------+--------+ | type | cnt | +------+--------+ | 2 | 38304 | | 1 | 761690 | +------+--------+

  1. mysql> explain select * from t_order t, t_order_ext s where s.order_id>=t.order_id and s.order_id<=t.order_id and t.express_type>5; 
  2. +----+-------------+-------+-------+----------------------+--------------+---------+------+------+------------------------------------------------+ 
  3. | id | select_type | table | type  | possible_keys        | key          | key_len | ref  | rows | Extra                                          | 
  4. +----+-------------+-------+-------+----------------------+--------------+---------+------+------+------------------------------------------------+ 
  5. |  1 | SIMPLE      | t     | range | PRIMARY,express_type | express_type | 1       | NULL |    1 | Using where                                    | 
  6. |  1 | SIMPLE      | s     | ALL   | order_id             | NULL         | NULL    | NULL |    1 | Range checked for each record (index map: 0x1) | 
  7. +----+-------------+-------+-------+----------------------+--------------+---------+------+------+------------------------------------------------+ 
  8. 2 rows in set (0.00 sec)

原标题:《叶问》第7期

7.index_subquery

前提说明:MySQL5.7.23、innodb表、“双1”

  1. mysql> explain select * from t_order where express_type=1 and user_id=100; 
  2. +----+-------------+---------+-------------+----------------------+----------------------+---------+------+------+----------------------------------------------------+ 
  3. | id | select_type | table   | type        | possible_keys        | key                  | key_len | ref  | rows | Extra                                              | 
  4. +----+-------------+---------+-------------+----------------------+----------------------+---------+------+------+----------------------------------------------------+ 
  5. |  1 | SIMPLE      | t_order | index_merge | user_id,express_type | user_id,express_type | 5,1     | NULL |    1 | Using intersect(user_id,express_type); Using where | 
  6. +----+-------------+---------+-------------+----------------------+----------------------+---------+------+------+----------------------------------------------------+ 
  7. 1 row in set (0.00 sec) 

首先,即便设置unique_checks=0,也无法往唯一索引中写入重复值。

  1. mysql> explain select user_id from t_order group by user_id; 
  2. +----+-------------+---------+-------+---------------+---------+---------+------+------+--------------------------+ 
  3. | id | select_type | table   | type  | possible_keys | key     | key_len | ref  | rows | Extra                    | 
  4. +----+-------------+---------+-------+---------------+---------+---------+------+------+--------------------------+ 
  5. |  1 | SIMPLE      | t_order | range | NULL          | user_id | 5       | NULL |    3 | Using index for group-by | 
  6. +----+-------------+---------+-------+---------------+---------+---------+------+------+--------------------------+ 
  7. 1 row in set (0.00 sec) 

在大表执行ddl的过程中,若临时中断,会发生什么状况,需要特别处理吗 ?

这种情况是mysql没有发现好的索引可用,速度比没有索引要快得多。

MySQL发现第1个匹配行后,停止为当前的行组合搜索更多的行。对于此项没有找到合适的例子,求指点。

对于Using intersect的例子可以参看下例,user_id与express_type发生了索引交叉合并。

见上面4.DERIVED的例子。其中第一行的type就是为system,第二行是const,这两种联接类型是最快的。

  1. mysql> explain select * from t_order where order_id in (select order_id from t_order where user_id=10); 
  2. +----+--------------------+---------+-----------------+-----------------+---------+---------+------+--------+-------------+ 
  3. | id | select_type        | table   | type            | possible_keys   | key     | key_len | ref  | rows   | Extra       | 
  4. +----+--------------------+---------+-----------------+-----------------+---------+---------+------+--------+-------------+ 
  5. |  1 | PRIMARY            | t_order | ALL             | NULL            | NULL    | NULL    | NULL | 100649 | Using where | 
  6. |  2 | DEPENDENT SUBQUERY | t_order | unique_subquery | PRIMARY,user_id | PRIMARY | 4       | func |      1 | Using where | 
  7. +----+--------------------+---------+-----------------+-----------------+---------+---------+------+--------+-------------+ 
  8. 2 rows in set (0.00 sec) 
  1. mysql> explain select * from t_order where user_id=100 or user_id is null; 
  2. +----+-------------+---------+-------------+---------------+---------+---------+-------+-------+-------------+ 
  3. | id | select_type | table   | type        | possible_keys | key     | key_len | ref   | rows  | Extra       | 
  4. +----+-------------+---------+-------------+---------------+---------+---------+-------+-------+-------------+ 
  5. |  1 | SIMPLE      | t_order | ref_or_null | user_id       | user_id | 5       | const | 50325 | Using where | 
  6. +----+-------------+---------+-------------+---------------+---------+---------+-------+-------+-------------+ 
  7. 1 row in set (0.00 sec) 

5.Using index

 

除了上面的三个说明,还需要注意rows的数值,多行之间的数值是乘积的关系,可以估算大概要处理的行数,如果乘积很大,那就很有优化的必要了。

  1. mysql> explain select * from (select order_id from t_order where order_id=100) a; 
  2. +----+-------------+------------+--------+---------------+---------+---------+------+------+-------------+ 
  3. | id | select_type | table      | type   | possible_keys | key     | key_len | ref  | rows | Extra       | 
  4. +----+-------------+------------+--------+---------------+---------+---------+------+------+-------------+ 
  5. |  1 | PRIMARY     | <derived2> | system | NULL          | NULL    | NULL    | NULL |    1 |             | 
  6. |  2 | DERIVED     | t_order    | const  | PRIMARY       | PRIMARY | 4       |      |    1 | Using index | 
  7. +----+-------------+------------+--------+---------------+---------+---------+------+------+-------------+ 
  8. 2 rows in set (0.03 sec) 
  1. mysql> explain select * from t_order; 
  2. +----+-------------+---------+------+---------------+------+---------+------+--------+-------+ 
  3. | id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows   | Extra | 
  4. +----+-------------+---------+------+---------------+------+---------+------+--------+-------+ 
  5. |  1 | SIMPLE      | t_order | ALL  | NULL          | NULL | NULL    | NULL | 100453 |       | 
  6. +----+-------------+---------+------+---------------+------+---------+------+--------+-------+ 
  7. 1 row in set (0.03 sec) 

按指定的范围进行检索,很常见。

4.ref_or_null

三.extra的说明

3.SUBQUERY:

当子查询是from子句时,其select_type为DERIVED。

  1. mysql> explain select * from t_order where user_id in (100,200,300); 
  2. +----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+ 
  3. | id | select_type | table   | type  | possible_keys | key     | key_len | ref  | rows | Extra       | 
  4. +----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+ 
  5. |  1 | SIMPLE      | t_order | range | user_id       | user_id | 5       | NULL |    3 | Using where | 
  6. +----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+ 
  7. 1 row in set (0.00 sec) 

该联接类型用于替换value IN (SELECT primary_key FROM single_table WHERE some_expr)这样的子查询的ref。注意ref列,其中第二行显示的是func,表明unique_subquery是一个函数,而不是一个普通的ref。

  1. mysql> explain select * from t_order where order_id=(select order_id from t_order where order_id=100); 
  2. +----+-------------+---------+-------+---------------+---------+---------+-------+------+-------------+ 
  3. | id | select_type | table   | type  | possible_keys | key     | key_len | ref   | rows | Extra       | 
  4. +----+-------------+---------+-------+---------------+---------+---------+-------+------+-------------+ 
  5. |  1 | PRIMARY     | t_order | const | PRIMARY       | PRIMARY | 4       | const |    1 |             | 
  6. |  2 | SUBQUERY    | t_order | const | PRIMARY       | PRIMARY | 4       |       |    1 | Using index | 
  7. +----+-------------+---------+-------+---------------+---------+---------+-------+------+-------------+ 
  8. 2 rows in set (0.03 sec) 

10.ALL

1.Distinct

加上extended后之后:

  1. mysql> explain select * from t_order a,t_order_ext b where a.order_id=b.order_id and a.order_id=100; 
  2. +----+-------------+-------+-------+---------------+----------+---------+-------+------+-------+ 
  3. | id | select_type | table | type  | possible_keys | key      | key_len | ref   | rows | Extra | 
  4. +----+-------------+-------+-------+---------------+----------+---------+-------+------+-------+ 
  5. |  1 | SIMPLE      | a     | const | PRIMARY       | PRIMARY  | 4       | const |    1 |       | 
  6. |  1 | SIMPLE      | b     | ref   | order_id      | order_id | 4       | const |    1 |       | 
  7. +----+-------------+-------+-------+---------------+----------+---------+-------+------+-------+ 
  8. 2 rows in set (0.00 sec) 

二.type的说明

这是性能很高的一种情况。当查询所需的数据可以直接从索引树中检索到时,就会出现。上面的例子中有很多这样的例子,不再多举例了。

5.index_merge

在t_order表中的order_id是主键,t_order_ext表中的order_id也是主键,该表可以认为是订单表的补充信息表,他们的关系是1对1,在下面的例子中可以看到b表的连接类型是eq_ref,这是极快的联接类型。

  1. mysql> explain select count(1) from t_order a left join t_order_ext b on a.order_id=b.order_id where b.order_id is null;  
  2. +----+-------------+-------+-------+---------------+--------------+---------+-----------------+--------+--------------------------------------+ 
  3. | id | select_type | table | type  | possible_keys | key          | key_len | ref             | rows   | Extra                                | 
  4. +----+-------------+-------+-------+---------------+--------------+---------+-----------------+--------+--------------------------------------+ 
  5. |  1 | SIMPLE      | a     | index | NULL          | express_type | 1       | NULL            | 100395 | Using index                          | 
  6. |  1 | SIMPLE      | b     | ref   | order_id      | order_id     | 4       | test.a.order_id |      1 | Using where; Using index; Not exists | 
  7. +----+-------------+-------+-------+---------------+--------------+---------+-----------------+--------+--------------------------------------+ 
  8. 2 rows in set (0.01 sec) 

1.system,const

下面的例子中user_id是一个检索范围,此时mysql会使用sort_union函数来进行索引的合并。而当user_id是一个固定值时,请参看上面type说明5.index_merge的例子,此时会使用union函数进行索引合并。

下面的例子在上面的例子上略作了修改,加上了条件。此时b表的联接类型变成了ref。因为所有与a表中order_id=100的匹配记录都将会从b表获取。这是比较常见的联接类型。

因为b表中的order_id是主键,不可能为NULL,所以mysql在用a表的order_id扫描t_order表,并查找b表的行时,如果在b表发现一个匹配的行就不再继续扫描b了,因为b表中的order_id字段不可能为NULL。这样避免了对b表的多次扫描。

  1. mysql> explain select * from t_order a left join t_order_ext b on a.order_id=b.order_id group by b.order_id; 
  2. +----+-------------+-------+------+---------------+----------+---------+-----------------+--------+---------------------------------+ 
  3. | id | select_type | table | type | possible_keys | key      | key_len | ref             | rows   | Extra                           | 
  4. +----+-------------+-------+------+---------------+----------+---------+-----------------+--------+---------------------------------+ 
  5. |  1 | SIMPLE      | a     | ALL  | NULL          | NULL     | NULL    | NULL            | 100395 | Using temporary; Using filesort | 
  6. |  1 | SIMPLE      | b     | ref  | order_id      | order_id | 4       | test.a.order_id |      1 |                                 | 
  7. +----+-------------+-------+------+---------------+----------+---------+-----------------+--------+---------------------------------+ 
  8. 2 rows in set (0.00 sec) 

在有排序子句的情况下很常见的一种情况。此时mysql会根据联接类型浏览所有符合条件的记录,并保存排序关键字和行指针,然后排序关键字并按顺序检索行。

该联接类型与上面的太像了,唯一的差别就是子查询查的不是主键而是非唯一索引。

  1. mysql> explain select * from t_order; 
  2. +----+-------------+---------+------+---------------+------+---------+------+--------+-------+ 
  3. | id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows   | Extra | 
  4. +----+-------------+---------+------+---------------+------+---------+------+--------+-------+ 
  5. |  1 | SIMPLE      | t_order | ALL  | NULL          | NULL | NULL    | NULL | 100649 |       | 
  6. +----+-------------+---------+------+---------------+------+---------+------+--------+-------+ 
  7. 1 row in set (0.00 sec) 

7.Using where

4.DERIVED:

2.eq_ref

当通过union来连接多个查询结果时,第二个之后的select其select_type为UNION。

表明可以在索引中找到分组所需的所有数据,不需要查询实际的表。

在进行统计时非常常见,此联接类型实际上会扫描索引树,仅比ALL快些。

user_id字段是一个可以为空的字段,并对该字段创建了一个索引。在下面的查询中可以看到联接类型为ref_or_null,这是mysql为含有null的字段专门做的处理。在我们的表设计中应当尽量避免索引字段为NULL,因为这会额外的耗费mysql的处理时间来做优化。

当union作为子查询时,其中第二个union的select_type就是DEPENDENT UNION。
第一个子查询的select_type则是DEPENDENT SUBQUERY。

8.Using sort_union(...)/Using union(...)/Using intersect(...)

  1. mysql> explain select * from t_order order by express_type; 
  2. +----+-------------+---------+------+---------------+------+---------+------+--------+----------------+ 
  3. | id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows   | Extra          | 
  4. +----+-------------+---------+------+---------------+------+---------+------+--------+----------------+ 
  5. |  1 | SIMPLE      | t_order | ALL  | NULL          | NULL | NULL    | NULL | 100395 | Using filesort | 
  6. +----+-------------+---------+------+---------------+------+---------+------+--------+----------------+ 
  7. 1 row in set (0.00 sec) 
id SELECT识别符。这是SELECT的查询序列号
select_type

SELECT类型,可以为以下任何一种:

  • SIMPLE:简单SELECT(不使用UNION或子查询)
  • PRIMARY:最外面的SELECT
  • UNION:UNION中的第二个或后面的SELECT语句
  • DEPENDENT UNION:UNION中的第二个或后面的SELECT语句,取决于外面的查询
  • UNION RESULT:UNION 的结果
  • SUBQUERY:子查询中的第一个SELECT
  • DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询
  • DERIVED:导出表的SELECT(FROM子句的子查询)
table

输出的行所引用的表

type

联接类型。下面给出各种联接类型,按照从最佳类型到最坏类型进行排序:

  • system:表仅有一行(=系统表)。这是const联接类型的一个特例。
  • const:表最多有一个匹配行,它将在查询开始时被读取。因为仅有一行,在这行的列值可被优化器剩余部分认为是常数。const表很快,因为它们只读取一次!
  • eq_ref:对于每个来自于前面的表的行组合,从该表中读取一行。这可能是最好的联接类型,除了const类型。
  • ref:对于每个来自于前面的表的行组合,所有有匹配索引值的行将从这张表中读取。
  • ref_or_null:该联接类型如同ref,但是添加了MySQL可以专门搜索包含NULL值的行。
  • index_merge:该联接类型表示使用了索引合并优化方法。
  • unique_subquery:该类型替换了下面形式的IN子查询的ref: value IN (SELECT primary_key FROM single_table WHERE some_expr) unique_subquery是一个索引查找函数,可以完全替换子查询,效率更高。
  • index_subquery:该联接类型类似于unique_subquery。可以替换IN子查询,但只适合下列形式的子查询中的非唯一索引: value IN (SELECT key_column FROM single_table WHERE some_expr)
  • range:只检索给定范围的行,使用一个索引来选择行。
  • index:该联接类型与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。
  • ALL:对于每个来自于先前的表的行组合,进行完整的表扫描。
possible_keys

指出MySQL能使用哪个索引在该表中找到行

key 显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL。
key_len 显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。
ref 显示使用哪个列或常数与key一起从表中选择行。
rows 显示MySQL认为它执行查询时必须检查的行数。多行之间的数据相乘可以估算要处理的行数。
filtered 显示了通过条件过滤出的行数的百分比估计值。
Extra

该列包含MySQL解决查询的详细信息

  • Distinct:MySQL发现第1个匹配行后,停止为当前的行组合搜索更多的行。
  • Not exists:MySQL能够对查询进行LEFT JOIN优化,发现1个匹配LEFT JOIN标准的行后,不再为前面的的行组合在该表内检查更多的行。
  • range checked for each record (index map: #):MySQL没有发现好的可以使用的索引,但发现如果来自前面的表的列值已知,可能部分索引可以使用。
  • Using filesort:MySQL需要额外的一次传递,以找出如何按排序顺序检索行。
  • Using index:从只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的列信息。
  • Using temporary:为了解决查询,MySQL需要创建一个临时表来容纳结果。
  • Using where:WHERE 子句用于限制哪一个行匹配下一个表或发送到客户。
  • Using sort_union(...), Using union(...), Using intersect(...):这些函数说明如何为index_merge联接类型合并索引扫描。
  • Using index for group-by:类似于访问表的Using index方式,Using index for group-by表示MySQL发现了一个索引,可以用来查 询GROUP BY或DISTINCT查询的所有列,而不要额外搜索硬盘访问实际的表。

mysql explain用法和结果的含义 2012-11-23 17:18:13

2.Not exists

9.Using index for group-by

编辑:智能科技 本文来源:金沙澳门官网网址cow详细介绍,explain用法和结果

关键词: