MySQL联合索引(abc)命中测试

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()
BEGIN
    DECLARE i INT DEFAULT 1;
    WHILE i <= 1000000 DO
        INSERT 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).

相关推荐
月光水岸New2 小时前
Ubuntu 中建的mysql数据库使用Navicat for MySQL连接不上
数据库·mysql·ubuntu
狄加山6752 小时前
数据库基础1
数据库
我爱松子鱼2 小时前
mysql之规则优化器RBO
数据库·mysql
chengooooooo3 小时前
苍穹外卖day8 地址上传 用户下单 订单支付
java·服务器·数据库
Rverdoser4 小时前
【SQL】多表查询案例
数据库·sql
Galeoto4 小时前
how to export a table in sqlite, and import into another
数据库·sqlite
人间打气筒(Ada)4 小时前
MySQL主从架构
服务器·数据库·mysql
leegong231114 小时前
学习PostgreSQL专家认证
数据库·学习·postgresql
喝醉酒的小白4 小时前
PostgreSQL:更新字段慢
数据库·postgresql
敲敲敲-敲代码4 小时前
【SQL实验】触发器
数据库·笔记·sql