MySQL EXPLAIN执行计划

一、MySQL EXPLAIN执行计划 介绍

EXPLAIN 关键字用于获取有关我们的 SQL 数据库如何在 MySQL 中执行查询的信息。它是 DESCRIBE 语句的同义词。实际上,DESCRIBE 关键字提供表结构信息,而 EXPLAIN 关键字提供查询执行计划。它是理解和优化MySQL中查询的强大工具,但开发人员很少使用它。它可以处理INSERTSELECTDELETEUPDATEREPLACE 查询。从MySQL 8.0.19 及更高版本开始,它也可以与 TABLE 语句一起使用。当我们在查询中使用该关键字时,它将处理语句并提供有关执行计划中每个步骤的信息,例如表的连接方式、表的顺序、估计的分区等。它返回单个或多个行来解释每个部分执行计划和执行顺序。

让我们借助一个例子来理解它。

二、MySQL EXPLAIN执行计划 示例

假设我们在示例数据库中有一个名为“ student_info ”和“ orders ”的表,其中包含以下数据:

如果我们想显示SELECT 语句的执行计划,我们可以使用如下SQL:

mysql> EXPLAIN SELECT * FROM student_info;  

此查询产生以下信息:

有时我们不想扫描整个表。在这种情况下,我们需要使用 INDEX 来查看基于指定条件的信息。执行以下语句在 student_info 表中创建索引:

mysql> create index student_id_index on student_info(stud_id);  

如果索引创建成功,它将产生以下输出:

现在,执行以下查询以避免数据库中的完整表扫描:

mysql> EXPLAIN SELECT * FROM student_info WHERE stud_id = 1;  

它将产生如下图所示的输出:

EXPLAIN SELECT s. stud_name, s.phone, orders.order_date, orders.prod_name  
FROM student_info AS s  
JOIN orders ON (s.stud_id = orders.order_id)  
WHERE s.stud_name = 'Barack';  

执行后,我们将得到如下图所示的输出:

在上面的输出中,我们可以看到两个表的 select_type 都是 SIMPLE。两个表都遵循一对多的关系。student_info 表的主键用作orders 表的外键。因此,第二行的 possible_keys 值为 order_id。对于 student_info 表,第一行中的过滤值是 12.50%,因为“Barack”是该表的第四个条目。对于订单表,第二行中的过滤值是 100%。这是因为必须检查订单表的所有值才能检索数据。

三、使用 UNION ALL 运算符的 SELECT 查询中的 EXPLAIN

UNION ALL 是一个运算符,它在使用 SELECT 查询时从相关表中返回所有具有重复项的匹配列值。下面的语句通过在 student_info 和 orders 表之间使用UNION ALL运算符显示了 EXPLAIN 输出。

EXPLAIN SELECT stud_id as ID FROM student_info  
UNION ALL  
SELECT order_id as ID FROM orders;  

它将产生以下输出,其中我们可以看到 select_type 的值为第二行的 UNION 并且 Extra 列的值是索引:

四、MySQL EXPLAIN执行计划 局限性

以下是 MySQL 中 EXPLAIN 关键字最常见的限制:

  • EXPLAIN 不提供有关触发器、存储函数或 UDF 将如何影响我们的查询的任何信息。
  • EXPLAIN 关键字不能用于存储过程。
  • EXPLAIN没有告诉您 MySQL 在查询执行期间所做的优化。
  • EXPLAIN产生的估计统计数据可能非常不准确。
  • EXPLAIN不会生成有关查询执行计划的所有信息。

五、MySQL EXPLAIN ANALYZE

EXPLAIN ANALYZE是一个用于查询的分析工具,显示有关 MySQL 将时间用于查询执行的位置以及原因的信息。它将计划查询、检测并执行它,同时计算行数并测量执行计划中各个点所花费的时间。当执行完成时,它将打印计划和测量而不是查询结果。

示例

EXPLAIN ANALYZE SELECT s. stud_name, s.phone, orders.order_date, orders.prod_name  
FROM student_info AS s  
JOIN orders ON (s.stud_id = orders.order_id)  
WHERE s.stud_name = 'Barack';   

输出结果为:

热门文章

优秀文章