mysql tuning ecplain (transfer)

Mysql Explain detailed explanation


1. Syntax

explain < table_name >

For example: explain select * from t3 where id=3952602;

2. explain output explanation

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

1.id
  i The understanding is the smooth identification of SQL execution, SQL is executed from big to small.

For example:
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
| ---+-------+-------------------+---------+------- --+------+------+-------+
| 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 | |
+----+---- ---------+------------+--------+-------- -+---------+---------+------+------+-------+

Obviously this SQL is Execution from the inside out is to execute upward from id=3.

2. select_type

is the select type, which can be as follows

(1) SIMPLE
Simple SELECT (without UNION or subqueries, etc.) eg:
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

is the outermost select in my understanding. For example:

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

The second or subsequent SELECT statement in UNION. For example
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

The second or subsequent SELECT statement in UNION depends on the outer query

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). The first SELECT in the

DEPENDENT SUBQUERY subquery, depending on the outer query 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

shows which table the data in this row is about.
Sometimes it's not the real table name, what you see is derivedx (x is a number, my understanding is the result of the first few steps)

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
| ---+-------+-------------------+---------+------- --+------+------+-------+
| 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

This column is very Important, shows which category the join uses, with or without indexes.
The join types from best to worst are const, eq_reg, ref, range, indexhe, and ALL 

(1).system

This is a special case of the const connection type. There is only one row in the table that satisfies the condition. As follows (the id on the t3 table is the 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

The table has at most one matching row, which will be read at the start of the query. Since there is only one row, the column values ​​in this row can be considered constant by the rest of the optimizer. const tables are fast because they are only read once!

const is used when comparing all parts of a PRIMARY KEY or UNIQUE index with a constant value. In the following query, tbl_name can be used for const tables:
SELECT * from tbl_name WHERE primary_key=1;
SELECT * from tbl_name WHERE primary_key_part1=1 and primary_key_part2=2;

eg:
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

For each combination of rows from the preceding table, read a row from this table. This is probably the best join type, except for const types. It is used when all parts of an index are joined and the index is a UNIQUE or PRIMARY KEY.

eq_ref can be used for indexed columns that are compared using the = operator. The comparison value can be a constant or an expression using a column of the table read before the table.

In the following example, MySQL can use eq_ref joins to process 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

for each A combination of rows from the preceding table, all rows with matching index values ​​will be read from this table. Use ref if the join uses only the leftmost prefix of the key, or if the key is not a UNIQUE or PRIMARY KEY (in other words, if the join cannot select a single row based on the key). This join type is good if the keys used match only a few rows.

ref can be used on indexed columns using the = or <=> operators.

In the following example, MySQL can use ref joins to process 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

This join type is like ref, but with the addition that MySQL can specifically search for rows containing NULL values. This join type optimization is often used in solving subqueries.

In the following example, MySQL can use ref_or_null join to process ref_tables:

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

(6). index_merge

This join type indicates that the index merge optimization method is used. In this case, the key column contains the list of used indexes, and key_len contains the longest key element of the used indexes.

E.g:
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

This type replaces the ref of an IN subquery of the form:

value IN (SELECT primary_key FROM single_table WHERE some_expr )
unique_subquery is an index lookup function that can completely replace subqueries and is more efficient.

(8).index_subquery

The join type is similar to unique_subquery. IN subqueries can be replaced, but only for non-unique indexes in subqueries of the form:

value IN (SELECT key_column FROM single_table WHERE some_expr)

(9).range

Retrieve only a given range of rows, using an index to select rows. The key column shows which index was used. key_len contains the longest key element of the index used. In this type the ref column is NULL.

When using the =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN or IN operators to compare key columns with constants, you can use 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 ,

1 row in set (0.02 sec)

(10).index

This join type is the same as ALL, except that only the index tree is scanned. This is usually faster than ALL because index files are usually smaller than data files.

MySQL can use this join type when a query uses only columns that are part of a single index.

(11). ALL

performs a full table scan for each combination of rows from the previous table. This is usually not good if the table is the first table not marked const, and is usually bad in its case. Often more indexes can be added instead of using ALL so that rows can be retrieved based on constant values ​​or column values ​​in previous tables.


5.possible_keys

possible_keys column indicates which index MySQL can use to find rows in this table. Note that this column is completely independent of the order of the table shown in the EXPLAIN output. This means that some keys in possible_keys cannot actually be used in the generated table order.

If the column is NULL, there is no associated index. In this case, you can improve your query performance by checking the WHERE clause to see if it references certain columns or columns suitable for indexing. If so, create an appropriate index and check the query again with EXPLAIN

6. key

The key column shows the key (index) that MySQL actually decided to use. If no index is selected, the key is NULL. To force MySQL to use or ignore indexes on the possible_keys column, use FORCE INDEX, USE INDEX, or IGNORE INDEX in the query.

7.key_len

The key_len column shows the key length that MySQL decides to use. If the key is NULL, the length is NULL.
The length of the index used. Shorter lengths are better without loss of accuracy 

8. ref

The ref column shows which column or constant is used along with the key to select a row from the table.

9. rows

The rows column shows the number of rows that MySQL thinks it must examine when executing the query.

10. Extra

This column contains the details of MySQL's solution query, as detailed below.

(1). Distinct 
Once MYSQL finds a row that matches the row, it will no longer search 

(2). Not exists 
MYSQL optimizes LEFT JOIN, Once it finds a row that matches the LEFT JOIN criteria, 

it does not search any further 

(3).Range checked for each 

Record (index map:#) 
does not find the ideal index, so for each combination of rows from the previous table, MYSQL checks which index is used and uses it to return rows from the table. This is one of the slowest joins using indexes 

(4). Using filesort 
When you see this, the query needs to be optimized. MYSQL takes an extra step to discover how to sort the returned rows. It sorts all rows according to the join type and the row pointers of all rows that store the sort key value and matching conditions 

(5). Using index 
column data is returned from a table that only uses the information in the index without the actual action of reading , which occurs when all the requested columns for the table are part of the same index 

(6). Using temporary 
When you see this, the query needs to be optimized. Here, MYSQL needs to create a temporary table to store the results, which usually happens on ORDER BY on different sets of columns, not on GROUP BY 

(7). Using where
a WHERE clause is used to limit which rows will be related to the next table match or return to the user. This can happen if you don't want to return all the rows in the table, and the join type is ALL or index, or there is something wrong with the query

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326355966&siteId=291194637