mysql-explain 查看 sql 执行过程
警告
本文最后更新于 2020-05-30 17:09,文中内容可能已过时。
在查询语句前加 explain
例:
mysql> explain select * from test where name=‘soulchild’\G; *************************** 1. row *************************** id: 1 select_type: SIMPLE table: test type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 5 Extra: Using where 1 row in set (0.00 sec)
说明:
id:SELECT 识别符。这是 SELECT 的查询序列号
select_type: 可以为以下任何一种
- SIMPLE: 简单 SELECT (不使用 UNION 或子查询)
- PRIMARY: 最外面的 SELECT
- UNION:UNION 中的第二个或后面的 SELECT 语句
- DEPENDENT UNION:UNION 中的第二个或后面的 SELECT 语句,取决于外面的查询
- UNION RESULT:UNION 的结果
- SUBQUERY: 子查询中的第一个 SELECT
- DEPENDENT SUBQUERY: 子查询中的第一个 SELECT, 取决于外面的查询
- DERIVED: 导出表的 SELECT (FROM 子句的子查询)
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: 对于每个来自于先前的表的行组合,进行完整的表扫描。
key: 显示 MySQL 实际决定使用的键 (索引)。如果没有选择索引,键是 NULL。
key_len: 显示 MySQL 决定使用的键长度。如果键是 NULL, 则长度为 NULL。
ref: 显示使用哪个列或常数与 key 一起从表中选择行。
rows: 显示 MySQL 执行查询时扫描的行数
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 查询的所有列,而不要额外搜索硬盘访问实际的表。
在 name 列创建普通索引,在查询
mysql> create index index_name on test(name);
mysql> explain select * from test where name=‘soulchild’\G;
*************************** 1. row *************************** id: 1 select_type: SIMPLE table: test type: ref possible_keys: index_name key: index_name key_len: 20 ref: const rows: 1 Extra: Using where; Using index
可以对比出有索引时,只扫描一行就查询到结果了。
请我喝杯水

