Code前端首页关于Code前端联系我们

MySQL 中带 IN 子句的语句是如何执行的

terry 2年前 (2023-09-26) 阅读数 48 #数据库

下面我们来说说 MySQL 中带 IN 子句的语句是如何执行的(以 MySQL 5.7 的 InnoDB 存储引擎为例)。

准备工作

为了故事的顺利发展,我们首先创建一个表:

CREATE TABLE t (
    id INT NOT NULL AUTO_INCREMENT,
    key1 VARCHAR(100),
    common_field VARCHAR(100),
    PRIMARY KEY (id),
    KEY idx_key1 (key1)
) Engine=InnoDB CHARSET=utf8;
复制代码

可以看到表t包含两个索引:

  • id 以列为主键的聚集索引
  • key1列列创建的二级索引

该表中现在有10,000条数据:

mysql> SELECT COUNT(*) FROM t;
+----------+
| COUNT(*) |
+----------+
|    10000 |
+----------+
1 row in set (0.00 sec)
复制代码

从B+树

我们现在要执行以下语句:

SELECT * FROM t WHERE 
    key1 >= 'b' AND key1 <= 'c';
复制代码

假设优化器选择使用二级索引来执行查询,则查询语句的执行图如下所示: MySQL中包含IN子句的语句是怎样执行的

提示:原谅me为复杂的B+对应的索引。树结构是一个极其简化的版本。为了强调最重要的一点,我们忽略页面结构并直接将所有叶节点记录显示在一起。我们要强调的要点是:B+树叶子节点中的记录是根据索引列值进行排序的。对于聚集索引来说,对应的B+树叶子节点中的记录是根据ID列进行排序的。对于 idx_key1 二级索引来说,对应的B+树节点中的记录是根据key1列进行排序的。

我们要查询key1范围内的记录,其值位于区间['b', 'c']。那么我们需要:

  • 第一遍 idx_key1索引对应的B+树快速定位到key1列值,如果'b',以及最左边的二级索引记录。二级索引记录包含对应的主键值。根据这个主键值,整条记录都在聚集索引中(这个过程称为回表),并被发送回服务器层,然后发送到客户端。
  • 记录以单链表的形式排列,键值从小到大,这样我们就可以沿着这个单链表找到下一条二级索引记录,并执行回表操作来传输整条记录一旦发送到服务器层后,就发送到客户端。
  • 继续查找记录单向链表,重复上述过程,直到找到的二级索引记录的key1列的值不满足key1

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门