BH4FFUBH4FFU

程序员
业余无线电爱好者

史上最强 | Mysql EXPLAIN详解 - 聊聊Extra

本文涉及到的内容比较多,预计阅读时间:30min

0x00 写在前面

使用explain关键字,除了看一下sql的join type,extra也是我们重点关注的一个信息。extra主要告诉我们,mysql是如何解析的sql。extra中的信息大家可能也并不陌生,比如常见的Using filesortUsing temporaryUsing index等。那这些信息具体代表什么意思,能给我们优化sql带来什么样的指导?还有哪些常见的extra信息?且听我慢慢道来...

如果对explain中的type不太了解的朋友,可以看我上一篇文章 史上最强 | Mysql EXPLAIN详解 - 聊聊Type
本文基于mysql 8.0.17

0x01 Backward index scan

The optimizer is able to use a descending index on an InnoDB table. Shown together with Using index.

解析
如果在sql中有order by xx desc, 优化器可以在InnoDB表上使用倒序索引。实际上,在mysql8.x,extra中并不会显示Backward index scan,而是Using index
在mysql5.7中,会显示Using index; Using filesort

举例

CREATE TABLE t1 (a INT PRIMARY KEY, b INT, KEY a_idx(a DESC, b ASC));
INSERT INTO t1 VALUES(1,1),(2,2),(3,3);
EXPLAIN SELECT * FROM t1 ORDER BY a DESC, b;

mysql 8.0:

mysql 5.7:

多说一句

  • 由于涉及到数据的存储,目前只支持InnoDB
  • Descending index 无法使用change buffer
  • Descneding index不支持fulltext或spatial index, 选择desc关键字会报错
  • GROUP BY不在隐式的保证顺序性,只有明确的指定asc/desc,才去确保顺序
  • MySQL 8.0之前,不管是否指定索引建的排序方式,都会忽略创建索引时候指定的排序方式(语法上不会报错),最终都会创建为ASC方式的索引

0x02 Child of 'table' pushed join@1

This table is referenced as the child of table in a join that can be pushed down to the NDB kernel. Applies only in NDB Cluster, when pushed-down joins are enabled.

解析
这个表被引用为可以下推到NDB内核的连接中的表的子表。 只适用于MySQL NDB集群,当启用了下推连接时。

举例
存在于NDB Cluster,笔者公司没有类似的环境。有兴趣的朋友可以自己研究一下。关于NDB可以参考一下:
https://cloud.tencent.com/developer/article/1055592

0x03 const row not found

For a query such as SELECT ... FROM tbl_name, the table was empty.

解析
官方文档:如果对一个空表进行简单查询,extra就是const row not found。官方文档这个地方描述的并不准确。比如,新建一张表(空表)

CREATE TABLE `t1` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

如下语句:

EXPLAIN select * from t1

执行计划:

如果将存储引擎由InnoDB变更为MyISAM,执行计划如下:

这文档,不靠谱的!不过还是从网上找到了一个例子。

举例

-- 创建表t1(有一条数据)
CREATE TABLE `t1` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
INSERT INTO t1 VALUES(1, 'a')    

-- 创建表t2(空表)
CREATE TABLE `t2` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

执行查询

EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id;

执行计划如下:

参考资料

MySQL · 引擎特性 · 8.0 Descending Index
Problem with joining to an empty table

本原创文章未经允许不得转载 | 当前页面:BH4FFU » 史上最强 | Mysql EXPLAIN详解 - 聊聊Extra

评论 1

文章评论已关闭!