1.建表
mysql创建一张表,表名:‘test_models’
- id列为 主键,int类型 ,自增
- a,b,c,d,e 全部是int(11)
- 为(a,b,c)添加一个联合索引 index_abc
执行语句:创建表
CREATE TABLE `test_models` (
`id` INT(11) NOT NULL AUTO_INCREMENT,`a` INT(11) DEFAULT NULL,`b` INT(11) DEFAULT NULL,`c` INT(11) DEFAULT NULL,`d` INT(11) DEFAULT NULL,`e` INT(11) DEFAULT NULL,PRIMARY KEY (`id`),KEY `index_abc` (`a`,`b`,`c`)
);
创建测试数据:
DELIMITER //CREATE PROCEDURE insert_random_data()
BEGINDECLARE i INT DEFAULT 1;WHILE i <= 1000000 DOINSERT INTO test_models (a, b, c, d, e)VALUES (FLOOR(RAND() * 1000), FLOOR(RAND() * 10000), FLOOR(RAND() * 100000), FLOOR(RAND() * 1000), FLOOR(RAND() * 1000));SET i = i + 1;END WHILE;
END //DELIMITER ;-- 调用存储过程
CALL insert_random_data();
执行该存储过程后,会生成 100 万条随机数据。这种方法适合 MySQL 存储过程,并且只需运行一次命令。
二.测试数据
通过,走联合索引(a,b,c)成功
EXPLAIN SELECT * FROM test_models WHERE a = 100 AND b = 1000 AND c = 10000;
三.具体测试示例
1.当我们通过where来表示的时候,只要是a开头的时候,都会走最左索引的原则来进行
2.当我们以b或c开头的时候,由于违背了最左的原则,导致无法走abc的索引
3.特殊情况分析,查询语句where a和c的时候
=和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序
mysql的查询优化器会帮你优化成索引可以识别的形式
四.总结
4.1 MySQL联合索引遵循最左前缀匹配规则,即从联合索引的最左列开始向右匹配,直到遇到匹配终止条件。
例如联合索引(col1, col2, col3), where条件为col1=a AND col2=b可命中该联合索引的(col1,col2)前缀部分, where条件为col2=b AND col3=c不符合最左前缀匹配,不能命中该联合索引。
4.2 匹配终止条件为范围操作符(如>, <, between, like等)或函数等不能应用索引的情况。
例如联合索引(col1, col2, col3), where条件为col1=a AND col2>1 AND col3=c, 在col2列上为范围查询,匹配即终止,只会匹配到(col1, col2),不能匹配到(col1, col2, col3).