MySQL 中带 IN 子句的语句是如何执行的
下面我们来说说 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';
复制代码
假设优化器选择使用二级索引来执行查询,则查询语句的执行图如下所示:
提示:原谅me为复杂的B+对应的索引。树结构是一个极其简化的版本。为了强调最重要的一点,我们忽略页面结构并直接将所有叶节点记录显示在一起。我们要强调的要点是:B+树叶子节点中的记录是根据索引列值进行排序的。对于聚集索引来说,对应的B+树叶子节点中的记录是根据ID列进行排序的。对于 idx_key1 二级索引来说,对应的B+树节点中的记录是根据key1列进行排序的。
我们要查询key1
范围内的记录,其值位于区间['b', 'c']
。那么我们需要:
- 第一遍
idx_key1
索引对应的B+
树快速定位到key1
列值,如果'b'
,以及最左边的二级索引记录。二级索引记录包含对应的主键值。根据这个主键值,整条记录都在聚集索引中(这个过程称为回表),并被发送回服务器层,然后发送到客户端。 - 记录以单链表的形式排列,键值从小到大,这样我们就可以沿着这个单链表找到下一条二级索引记录,并执行回表操作来传输整条记录一旦发送到服务器层后,就发送到客户端。
- 继续查找记录单向链表,重复上述过程,直到找到的二级索引记录的key1列的值不满足
key1
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。