1. 前言
偶然看到一个技术群,对一道关于联合索引的讨论。面试题如下:
a_b_c_index 三列复合索引 a =1 and b<100 and c=5 这个查询 会用到索引的那几部分?
复制代码
先说下个人经过本人查询多方资料得到的结论, 只会用到 a 和 b部分(这里和群里小伙伴的讨论结果一致,如果有疑问可以后续探讨)。
2. 验证
要验证这个需要观察explain结果中 key、key_len。key 代表用到的索引。key_len 代表索引使用的字节数,当索引的类型为int且默认值可以为null的时候,用到索引则key_len为4。
接下来是表结构:
CREATE TABLE `test` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`a` int unsigned NOT NULL DEFAULT '0',
`b` int unsigned NOT NULL DEFAULT '0',
`c` int unsigned NOT NULL,
`asda` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `a_b_c_index` (`a`,`b`,`c`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
复制代码
分别执行下面的sql。
explain SELECT * FROM test.test where a=2 and b=12 and c=12;
复制代码
根据key_len和key两个字段发现,该sql用到了索引的全部部分。
explain SELECT * FROM test.test where a=2 and b>12 and c=12;
复制代码
其中key_len结果是8,说明只用到了,索引的两个部分,但无法确认是abc中的哪些用到了索引。
explain SELECT * FROM test.test where a=2 and b>12;
复制代码
其中key_len结果是8,说明a和b都用到了索引。
explain SELECT * FROM test.test where a=2 and c=12;
复制代码
其中key_len结果是4,发现其中只有一个字段用到了索引。
explain SELECT * FROM test.test where c=12;
复制代码
这里没用到索引。
根据以上的结果,可以得到那个面试题的结论。只会用到 a 和 b部分用到了索引。
3. 总结
对于联合索引最左原则的总结如下:
1.联合索引的最左侧列要在查询语句中才能用到联合索引。
2.查询语句中,存在最左侧连续的字段,且不能有范围查询的联合索引部分会生效。
3.最左原则在遇到范围查询后,之后往右的字段,索引不生效。