以下两个sql是如何使用索引的?

mysql> show create table s1;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| s1    | CREATE TABLE `s1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `key1` varchar(100) DEFAULT NULL,
  `key2` int(11) DEFAULT NULL,
  `key3` varchar(100) DEFAULT NULL,
  `key_part1` varchar(100) DEFAULT NULL,
  `key_part2` varchar(100) DEFAULT NULL,
  `key_part3` varchar(100) DEFAULT NULL,
  `common_field` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_key2` (`key2`),
  KEY `idx_key1` (`key1`),
  KEY `idx_key3` (`key3`),
  KEY `idx_key_part` (`key_part1`,`key_part2`,`key_part3`)
) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=utf8 |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
mysql> explain select key_part1 from s1 where key_part1 = "a" and key_part2 > "b" AND key_part3 > "c";
+----+-------------+-------+------------+-------+---------------+--------------+---------+------+------+----------+--------------------------+
| id | select_type | table | partitions | type  | possible_keys | key          | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+-------+------------+-------+---------------+--------------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | s1    | NULL       | range | idx_key_part  | idx_key_part | 606     | NULL |    1 |    33.33 | Using where; Using index |
+----+-------------+-------+------------+-------+---------------+--------------+---------+------+------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)

该explain结果中,key字段信息表明该查询使用到了索引: idx_key_part;Extra信息里面包含了Using whereUsing index,其中Using where代表该查询需要mysql server层进行判断,Using index代表该查询使用到了覆盖索引的特性,不需要回表操作。
所以该sql的执行流程是,mysql存储引擎层将满足key_part1 = "a"条件的第一条记录返回给mysql server层,由于该索引是联合索引(包含key_part1,key_part2,key_part3这三个字段),所以除了key_part1字段外,其他字段也一起会返回给server层,然后server层判断该记录是否符合查询条件,如果符合发送给客户端,否者不发送;然后server层继续向存储层要下一条记录,继续判断,直到第一条不满足key_part1 = "a"条件的记录为止,然后存储层告诉server层,查询完毕。

mysql> explain select * from s1 where key_part1 = "a" and key_part2 > "b" AND key_part3 > "c";
+----+-------------+-------+------------+-------+---------------+--------------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type  | possible_keys | key          | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+-------+------------+-------+---------------+--------------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | s1    | NULL       | range | idx_key_part  | idx_key_part | 606     | NULL |    1 |    33.33 | Using index condition |
+----+-------------+-------+------------+-------+---------------+--------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)

explain结果中,key字段信息表明该查询使用到了索引: idx_key_part;Extra信息为Using index condition说明该sql使用了innodb引擎的Index Condition PushDown的能力,即索引下推;
执行流程如下:mysql存储引擎层将满足key_part1 = "a"条件的第一条记录,继续判断该记录是否满足key_part2 > "b" AND key_part3 > "c"条件,如果满足返回给server层,否者不返回;直到第一条不满足key_part1 = "a"条件的记录为止,查询完毕。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容