Detailed explanation of sql explain

The explain shows how MySQL uses indexes to process select statements and join tables. Can help choose better indexes and write more optimized query statements.

To use it, just add explain before the select statement:

Such as:

explain select surname,first_name form a,b where a.id=b.id 

1、EXPLAIN tbl_name

EXPLAIN tbl_name is a synonym for DESCRIBE tbl_name or SHOW COLUMNS FROM tbl_name.

2、EXPLAIN [EXTENDED] SELECT select_options

If you put the keyword EXPLAIN before a SELECT statement, MySQL will explain how it handles the SELECT, providing information about how the tables are joined and the order in which they are joined.

With EXPLAIN, you know when you must index a table to get a faster SELECT that uses the index to find records.

You can also know whether the optimizer joins the tables in an optimal order. To force the optimizer to follow the join order of a SELECT statement in table naming order, the statement should begin with STRAIGHT_JOIN instead of just SELECT.

EXPLAIN returns one row of information for each table used in the SELECT statement. Tables are listed in the order they will be read by MySQL during query processing. MySQL resolves all joins in a single-sweep multi-join fashion. This means that MySQL reads a row from the first table, then finds a matching row in the second table, then in the third table and so on. When all tables are processed, it outputs the selected columns and returns the table list until it finds a table with more matching rows. Read in the next row from this table and continue processing the next table.

When using the EXTENDED keyword, EXPLAIN produces additional information that can be viewed with SHOW WARNINGS. This information shows the optimizer qualifies the table and column names in the SELECT statement, what the SELECT statement looks like after the optimization rules are rewritten and executed, and may also include other annotations for the optimization process.

Each output row of EXPLAIN provides information about a table, and each row includes the following columns:

id: SELECT identifier. This is the query sequence number for the SELECT.

select_type: SELECT type.

  1. SIMPLE: Simple SELECT (without using UNION or subqueries)
  2. PRIMARY: the outermost SELECT
  3. UNION: The second or subsequent SELECT statement in UNION
  4. DEPENDENT UNION: The second or subsequent SELECT statement in the UNION, depending on the outer query
  5. UNION RESULT: The result of the UNION
  6. SUBQUERY: The first SELECT in a subquery
  7. DEPENDENT SUBQUERY: The first SELECT in a subquery, depending on the outer query
  8. DERIVED: SELECT of the derived table (subquery of the FROM clause)

table: table name

type: join type

  1. system: The table has only one row (= system table). This is a special case of the const join type.
  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 is used when comparing all parts of a PRIMARY KEY or UNIQUE index with a constant value.
  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.
  4. ref: For each 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.
  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.
  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.
  7. unique_subquery: This type replaces the ref of the IN subquery of the following form: value IN (SELECT primary_key FROMsingle_table WHERE some_expr); unique_subquery is an index lookup function that can completely replace the subquery and is more efficient.
  8. index_subquery: This 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
  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.
  11. all:对于每个来自于先前的表的行组合,进行完整的表扫描。如果表是第一个没标记const的表,这通常不好,并且通常在它情况下很差。通常可以增加更多的索引而不要使用ALL,使得行能基于前面的表中的常数值或列值被检索出。

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

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

key_len:key_len列显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。注意通过key_len值我们可以确定MySQL将实际使用一个多部关键字的几个部分。

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

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

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

  1. Distinct:MySQL发现第1个匹配行后,停止为当前的行组合搜索更多的行。
  2. Not exists:MySQL能够对查询进行LEFT JOIN优化,发现1个匹配LEFT JOIN标准的行后,不再为前面的的行组合在该表内检查更多的行。
  3. range checked for each record (index map: #):MySQL没有发现好的可以使用的索引,但发现如果来自前面的表的列值已知,可能部分索引可以使用。对前面的表的每个行组合,MySQL检查是否可以使用range或index_merge访问方法来索取行。
  4. Using filesort:MySQL需要额外的一次传递,以找出如何按排序顺序检索行。通过根据联接类型浏览所有行并为所有匹配WHERE子句的行保存排序关键字和行的指针来完成排序。然后关键字被排序,并按排序顺序检索行。
  5. Using index:从只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的列信息。当查询只使用作为单一索引一部分的列时,可以使用该策略。
  6. Using temporary:为了解决查询,MySQL需要创建一个临时表来容纳结果。典型情况如查询包含可以按不同情况列出列的GROUP BY和ORDER BY子句时。
  7. Using where:WHERE子句用于限制哪一个行匹配下一个表或发送到客户。除非你专门从表中索取或检查所有行,如果Extra值不为Using where并且表联接类型为ALL或index,查询可能会有一些错误。
  8. Using sort_union(...), Using union(...), Using intersect(...):这些函数说明如何为index_merge联接类型合并索引扫描。
  9. Using index for group-by:类似于访问表的Using index方式,Using index for group-by表示MySQL发现了一个索引,可以用来查询GROUP BY或DISTINCT查询的所有列,而不要额外搜索硬盘访问实际的表。并且,按最有效的方式使用索引,以便对于每个组,只读取少量索引条目。

通过相乘EXPLAIN输出的rows列的所有值,你能得到一个关于一个联接如何的提示。这应该粗略地告诉你MySQL必须检查多少行以执行查询。当你使用max_join_size变量限制查询时,也用这个乘积来确定执行哪个多表SELECT语句。

Guess you like

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