Explain关键字详解.pdf
Explain关键字是MySQL中的一个重要工具,它能够帮助数据库管理员和开发人员深入理解SQL语句的执行计划。通过分析执行计划,我们可以优化查询语句,提高数据库性能。 Explain关键字可以提供每个SELECT查询的执行细节。在一个复杂的SQL查询语句中可能包含多个SELECT关键字,Explain关键字能够为每个查询分配一个唯一的id值。这个id值表示了查询的执行顺序以及它们在查询中的层级关系。针对单表的访问方法被称为type,常用的访问方法包括ALL(全表扫描)、index(索引全扫描)、range(索引范围扫描)、ref(非唯一索引查找)、eq_ref(唯一索引查找)等。 接下来,我们来探讨Explain输出结果中的各个列: select_type表示查询的类型,它包括SIMPLE、PRIMARY、UNION、UNION RESULT等。SIMPLE表示没有子查询或UNION的查询,PRIMARY表示最外层的查询或最内层的查询,UNION表示UNION中的第二个或之后的查询,UNION RESULT表示从UNION的临时表检索结果的select。 table列显示了正在访问的表名,或者对于子查询来说,显示的是子查询的ID。 partitions列显示了查询将访问的表所使用的分区信息。如果表没有分区,那么显示NULL。 type列显示了表的连接类型。一个好的连接类型是ref或更佳,差的是ALL。system是type列的最优值,表示表只有一行,即const的特例。 possible_keys列给出了MySQL在搜索表记录时可能使用到的索引。然而,即便这个列有值,实际使用的索引可能与possible_keys列中的不同,实际使用的索引会在key列显示。 key列显示了实际使用到的索引,如果没有使用到索引,这个值会是NULL。 key_len列表示了实际使用到的索引的长度,这是根据索引的定义和数据类型来计算得出的。 ref列显示了索引列与哪些列或常数等值匹配。 rows列预估了将要读取的记录条数,这个预估值是基于统计信息和索引策略得出的。 filtered列显示了表经过搜索条件过滤后,剩余记录的百分比。这个值是根据表的总行数乘以过滤条件后剩下的百分比计算得出的。 Extra列提供了额外的信息,这些信息可以是关于查询性能的提示,例如“Using index”表示MySQL将只使用索引来获取所需数据,或者“Using where”表示MySQL在索引之外的列上施加了where条件来过滤数据。 举个例子,当我们执行以下查询: ```sql mysql> explain select * from t1 join t2; ``` 执行结果将包括上述提到的列,例如: ``` +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------------------------+ | 1 | SIMPLE | t1 | NULL | ALL | NULL | NULL | NULL | NULL | 8 | 100.00 | NULL | | 1 | SIMPLE | t2 | NULL | ALL | NULL | NULL | NULL | NULL | 8 | 100.00 | Using join buffer (Block Nested Loop) | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------------------------+ ``` 如果查询中包含子查询或者UNION语句,那么每个SELECT关键字都会有一个唯一的id值。 例如,当查询中包含子查询时: ```sql mysql> explain select * from (select * from t1 where id=1) as subquery; ``` 输出结果将包含子查询的id值: ``` +----+-------------+------------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+------------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ | 1 | PRIMARY | <subquery> | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | NULL | | 2 | SUBQUERY | t1 | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | NULL | +----+-------------+------------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ ``` 在这个例子中,主查询(外部查询)和子查询(内部查询)都有一个唯一的id值,并且可以通过id值看到查询执行的顺序。 Explain关键字的使用非常广泛,它不仅可以用于SELECT语句,还可以用于DELETE、INSERT、REPLACE和UPDATE语句。通过分析Explain的输出结果,我们可以找到影响查询性能的瓶颈,优化查询语句,提高数据库操作的效率。