MySQL 复合索引测试

对MySQL复合索引结合具体示例,各条件下索引使用情况的运行结果及分析。

目录

复合索引示例

创建表

新增数据

查询数据

选项A

SQL查询

explain分析

选项B

SQL查询

explain分析

选项C

SQL查询

explain分析

选项D

SQL查询

explain分析

选项E

SQL查询

explain分析

总结


复合索引示例

假设某个表有一个联合索引(c1,c2,c3,c4)。

A where c1 = ? and c2 = ? and c4 > ? and c3 = ?

B where c1 = ? and c2 = ? and c4 = ? order by c3

C where c1 = ? and c4 = ? group by c3, c2

D where c1 = ? and c5 = ? order by c2, c3

E where c1 = ? and c2 = ? and c5=? order by c2, c3

有谁知道下面A-E能否可以使用索引!!为什么?

创建表

创建一个表,表引擎为MYISAM,并设置包含四个列的复合索引。

SQL语句如下:

sql 复制代码
CREATE TABLE `fuhe` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `c1` char(1) DEFAULT '',
  `c2` char(1) DEFAULT '',
  `c3` char(1) DEFAULT '',
  `c4` char(1) DEFAULT '',
  `c5` char(1) DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `c1` (`c1`,`c2`,`c3`,`c4`) USING BTREE
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

新增数据

在上述表中新增部分数据,语句如下:

sql 复制代码
INSERT INTO `test`.`fuhe` (`id`, `c1`, `c2`, `c3`, `c4`, `c5`) VALUES ('1', 'a', 'b', 'c', 'd', 'e');
INSERT INTO `test`.`fuhe` (`id`, `c1`, `c2`, `c3`, `c4`, `c5`) VALUES ('2', 'A', 'b', 'c', 'd', 'e');
INSERT INTO `test`.`fuhe` (`id`, `c1`, `c2`, `c3`, `c4`, `c5`) VALUES ('3', 'a', 'B', 'c', 'd', 'e');

查询数据

选项A

SQL查询

where c1 = ? and c2 = ? and c4 > ? and c3 = ?

sql 复制代码
# where c1 = ? and c2 = ? and c4 > ? and c3 = ?
SELECT * FROM `fuhe` where c1 = 'a' and c2 = 'b' and c4 > 'a' and c3 = 'c';

运行结果:

explain分析
sql 复制代码
explain SELECT * FROM `fuhe` where c1 = 'a' and c2 = 'b' and c4 > 'a' and c3 = 'c';

运行结果:

说明:

通过key_len属性12可知,utf8每个索引长度为3,使用了4列的索引;故复合索引的c1 c2 c3 c4列索引都使用上了。因为c4是范围查找,所以type类型为range。

选项B

SQL查询

where c1 = ? and c2 = ? and c4 = ? order by c3

sql 复制代码
# where c1 = ? and c2 = ? and c4 = ? order by c3
SELECT * FROM `fuhe` where c1 = 'a' and c2 = 'b' and c4 = 'd' order by c3;

运行结果:

explain分析
sql 复制代码
explain SELECT * FROM `fuhe` where c1 = 'a' and c2 = 'b' and c4 = 'd' order by c3;

运行结果:

说明:

使用了复合索引的c1 c2列,c3列只是参与了排序。如果c3列没有索引就会进行文件排序。

选项C

SQL查询

where c1 = ? and c4 = ? group by c3, c2

sql 复制代码
# where c1 = ? and c4 = ? group by c3, c2
SELECT * FROM `fuhe` where c1 = 'a' and c4 = 'd' group by c3, c2;

运行结果:

explain分析
sql 复制代码
explain SELECT * FROM `fuhe` where c1 = 'a' and c4 = 'd' group by c3, c2;

运行结果:

说明:

只使用了复合索引的c1列,而且由于group by并不是按照索引顺序进行分组的,导致使用了临时表和文件排序。

选项D

SQL查询

where c1 = ? and c5 = ? order by c2, c3

sql 复制代码
# where c1 = ? and c5 = ? order by c2, c3
SELECT * FROM `fuhe` where c1 = 'a' and c5 = 'e' order by c2, c3;

运行结果:

explain分析
sql 复制代码
explain SELECT * FROM `fuhe` where c1 = 'a' and c5 = 'e' order by c2, c3;

运行结果:

说明:

通过索引长度判断,只使用到了复合索引的第一列c1,c2 c3列参与了排序,因为c5列未创建索引故using where。

选项E

SQL查询

where c1 = ? and c2 = ? and c5=? order by c2, c3

sql 复制代码
# where c1 = ? and c2 = ? and c5=? order by c2, c3
SELECT * FROM `fuhe` where c1 = 'a' and c2 = 'b' and c5 = 'e' order by c2, c3;

运行结果:

explain分析

sql 复制代码
explain SELECT * FROM `fuhe` where c1 = 'a' and c2 = 'b' and c5 = 'e' order by c2, c3;

运行结果:

说明:

使用了复合索引的前两列,因为是按照索引顺序进行排序的,c2 c3列参与了排序,最后的c5没有创建索引,故使用了where条件,其他都是在索引树上扫描的。

总结

对MySQL复合索引结合具体示例,各条件下索引使用情况的运行结果及分析。

相关推荐
xhbh666几秒前
【实战避坑】MySQL自增主键(AUTO_INCREMENT)全解:从锁机制、间隙问题到分库分表替代方案
android·数据库·mysql·mysql自增主键
hh真是个慢性子15 分钟前
mongodb慢查询优化 速度欻欻滴~
数据库·mongodb·性能优化·慢查询
色空大师22 分钟前
【MongoDB的RLE压缩数据存储】
数据库·mongodb
安当加密23 分钟前
通过TDE透明加密实现人大金仓数据库的免改造存储加密方案
数据库·金仓·透明加密
养生技术人25 分钟前
Oracle OCP认证考试题目详解082系列第49题
运维·数据库·sql·oracle·database·开闭原则·ocp
white-persist35 分钟前
SQL 注入详解:从原理到实战
前端·网络·数据库·sql·安全·web安全·原型模式
Databend1 小时前
Raft 中的 IO 执行顺序:内存状态与持久化状态的陷阱
数据库
兜兜风d'2 小时前
redis字符串命令
数据库·redis·缓存
忧郁的蛋~3 小时前
EFcore查询a表中符合b表列的值
数据库
xwz小王子3 小时前
ManipulationNet:开启真实世界机器人操作基准测试新时代
数据库·机器人