mysql联合索引,abc的争议实践

原因

在一次和同事讨论mysql联合索引的面试题时出现了争议。主要问题是:a、b、c三个字段作为联合索引,b、c;和a、c情况到底会不会命中索引?

网上查阅相关博客发现很多答案不一样,于是我干脆亲手操作实验一下 ,我使用的mysql版本是5.6

一:创建表

为了更直接贴合面试题,字段直接用AA,BB,CC表示

create table IF NOT EXISTS TEST_COMPOSITE_INDEX
(
`TID` BIGINT  NOT NULL AUTO_INCREMENT,
`AA` VARCHAR(50) NOT NULL DEFAULT '' ,
`BB` VARCHAR(50) NOT NULL DEFAULT '',
`CC` VARCHAR(50) NOT NULL DEFAULT '',
`DD` VARCHAR(50) NOT NULL DEFAULT '',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`TID`),
KEY `index_comp` (`AA`,`BB`,`CC`)
)ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4;

sql中我们有两个索引,一:主键TID,二:AA、BB、CC组成的联合索引:index_comp

二:插入数据

insert into TEST_COMPOSITE_INDEX (AA,BB,CC,DD)VALUE('A1','B1','C1','D1');
insert into TEST_COMPOSITE_INDEX (AA,BB,CC,DD)VALUE('A2','B2','C2','D2');
insert into TEST_COMPOSITE_INDEX (AA,BB,CC,DD)VALUE('A3','B3','C3','D3');
insert into TEST_COMPOSITE_INDEX (AA,BB,CC,DD)VALUE('A4','B4','C4','D4');
insert into TEST_COMPOSITE_INDEX (AA,BB,CC,DD)VALUE('A5','B5','C5','D5');
insert into TEST_COMPOSITE_INDEX (AA,BB,CC,DD)VALUE('A6','B6','C6','D6');
insert into TEST_COMPOSITE_INDEX (AA,BB,CC,DD)VALUE('A7','B7','C7','D7');
insert into TEST_COMPOSITE_INDEX (AA,BB,CC,DD)VALUE('A8','B8','C8','D8');
insert into TEST_COMPOSITE_INDEX (AA,BB,CC,DD)VALUE('A9','B9','C9','D9');
insert into TEST_COMPOSITE_INDEX (AA,BB,CC,DD)VALUE('A10','B10','C10','D10');

三:查看执行计划
我们分别查看以下执行计划:

EXPLAIN select * FROM TEST_COMPOSITE_INDEX tci where tci.tid='3' ;
EXPLAIN select * FROM TEST_COMPOSITE_INDEX tci where tci.AA='A1';
EXPLAIN select * FROM TEST_COMPOSITE_INDEX tci where tci.BB='B1';
EXPLAIN select * FROM TEST_COMPOSITE_INDEX tci where tci.CC='C1' ;
EXPLAIN select * FROM TEST_COMPOSITE_INDEX tci where tci.AA='A1' AND tci.CC='C1';
EXPLAIN select * FROM TEST_COMPOSITE_INDEX tci where tci.BB='B1' AND tci.CC='C1';
EXPLAIN select * FROM TEST_COMPOSITE_INDEX tci where tci.AA='A1' AND tci.BB='B1';

以下结果按顺序展示,我们一个个看:

第一个:

首先第一个使用主键查询,可以看到执行计划中说明使用了主键,扫描行数是1,非常高效

第二个:

EXPLAIN select * FROM TEST_COMPOSITE_INDEX tci where tci.AA='A1';


可以看到同样使用了索引,这次使用的是我们创建的联合索引索引:index_comp。注意key_len:索引使用的字节数,这个后面会用作对比

第三、四个:

EXPLAIN select * FROM TEST_COMPOSITE_INDEX tci where tci.BB='B1';
EXPLAIN select * FROM TEST_COMPOSITE_INDEX tci where tci.CC='C1' ;



只是使用BB或者CC字段,并不会使用索引,扫描行数10

第五个:

EXPLAIN select * FROM TEST_COMPOSITE_INDEX tci where tci.AA='A1' AND tci.CC='C1';

这里是我们有争议的一个点,可以看到的确使用了索引,但是key_len索引使用的字节数是152和第二个语句只用A查询,使用的字节数是一致的,所以这句的结论是:A、C查询的时候虽然使用了索引,实际其实只用了A,而不是AC

第六个:

EXPLAIN select * FROM TEST_COMPOSITE_INDEX tci where tci.BB='B1' AND tci.CC='C1';


显而易见,B、C查询的时候并不会使用索引

第七个

EXPLAIN select * FROM TEST_COMPOSITE_INDEX tci where tci.AA='A1' AND tci.BB='B1';

最后是正常使用的联合索引,遵循最左匹配,索引使用的字节数:304,正好是之前命中单个字段的双倍

最后补充说明面试中可能碰到的问题:

如果是组合索引,且遵循最左匹配,如果其中有字段是范围查询,那么:命中的字段只会到范围查询那个字段,比如:
EXPLAIN select * FROM TEST_COMPOSITE_INDEX tci where tci.AA>'A1' AND tci.BB='B1';
那么这次查询使用的索引字段只有:AA,而不会使用BB

mysql组合索引,abc索引命中相关推荐

  1. mysql 组合主键索引_mysql 组合索引带主键ID的问题

    场景: mysql 5.7 某表 t_apply_info 上的2个索引,一个组合索引带了 主键字段 ID,另一个是同字段的单列索引 例如: KEY idx_1 (apply_serial_no,id ...

  2. mysql如何优化联合索引abc使用

    目录 一.数据背景 二.key-len列的计算规则 三.SQL执行测试 1)sql执行 a,b,c字段都存在 2)sql执行 a,b,c部分索引字段为查询条件 3)针对条件,优化索引 四.总结 mys ...

  3. MySQL联合索引(abc)命中规则

    1.建表 mysql创建一张表,表名:'test_models' id列为 主键,int类型 ,自增 a,b,c,d,e 全部是int(11) 为(a,b,c)添加一个联合索引 index_abc 执 ...

  4. mysql 组合索引 or_mysql索引优化实例(单列索引与组合索引)

    索引一般用于在数据规模大时对查询进行优化的一种机制,对于一般的查询来说,mysql会去遍历整个表,来查询符合要求的结果: 如果借助于mysql索引,mysql会将要索引的字段按照一定的算法进行处理,并 ...

  5. mysql联合索引abc

    mysql 联合索引 复合索引 (abc) 命中率:在工作中经常会使用到联合索引,在百度查询多很多资料也有说法不一的.给大家实测下100w数据下查询命中率,废话不多说.上干货: 创建测试表: SET ...

  6. mysql组合索最左_MySQL组合索引和最左匹配原则

    可以看到该查询使用到了索引 EXPLAIN SELECT * FROM student WHERE id = 2 AND name = 'defghijk' and age = 8; 可以看到该查询使 ...

  7. mysql 组合索引

    MySQL单列索引是我们使用MySQL数据库中经常会见到的,MySQL单列索引和组合索引的区别可能有很多人还不是十分的了解,下面就为您分析两者的主要区别,供您参考学习. 为了形象地对比两者,再建一个表 ...

  8. mysql组合索引与字段顺序

    转自:http://www.cnblogs.com/sunss/archive/2010/09/14/1826112.html 很多时候,我们在mysql中创建了索引,但是某些查询还是很慢,根本就没有 ...

  9. Mysql组合索引使用和用法

    下列转自:http://www.tech-q.cn/archiver/tid-11673.html 很多时候,我们在mysql中创建了索引,但是某些查询还是很慢,根本就没有使用到索引!一般来说,可能是 ...

  10. mysql表关联的索引命中失败 range checked for each record

    mysql表关联的索引命中失败和由此带来的思考 ###问题描述 最近翻了慢查询日志,大多数都是备份,夜晚的临时查询表生成,但是偶尔有几句是早年间留下的legend code留下的错误.有几个显示的问题 ...

最新文章

  1. 你见过的最全面的python重点
  2. 网友写的ELK安装步骤
  3. sql语句使用foreach报错
  4. fst java_java快速序列化库FST
  5. php科学计数法转string,php如何将科学计数法转数字
  6. 利用Spring的AbstractRoutingDataSource解决多数据源的读写分离问题
  7. 进程间通讯(一)--邮件槽
  8. Springboot整合zookeeper
  9. std::map的使用
  10. 7.上传自己的代码到 composer
  11. PXE+NFS+FTP+kickstarter无人值守安装linux系统
  12. 16款app源码下载收集
  13. 【PAT】A1150 Travelling Salesman Problem【中国邮递员问题】
  14. IE不支持使用for in语法
  15. SpringCloud Gateway网关为认证中心和用户微服务构建统一的认证授权入口
  16. 电子商务计算机和英语作文,电子商务的优缺点英语作文_电子商务英语作文
  17. 恢复Cisco 2960交换机密码
  18. 循环肿瘤细胞(circulating tumor cells,CTCs)
  19. 如何实现web浏览器无插件播放视频监控直播?
  20. 非标资产与标准资产_资产商店行动新闻– 2011年6月

热门文章

  1. Linux开发工具(3)——gcc/g++
  2. Linux编译器-gcc/g++的使用
  3. 嵌入式系统基于linux的优点
  4. 计算机桌面自动调转什么原因,电脑壁纸自动改变的解决方法-电脑自学网
  5. 认识(大端--小端)端模式
  6. ppt太大发不了邮件怎么办?
  7. 电脑连上网,可以登录qq、微信,但是打不开网页,怎么办?
  8. R语言glm函数构建二分类logistic回归模型、epiDisplay包logistic.display函数获取模型汇总统计信息(自变量初始和调整后的优势比及置信区间,回归系数的Wald检验的p值
  9. tcp 如何维护长连接
  10. Nuxt - 自定义页面布局,<Nuxt /> 个性化多套模板(一个项目内既要有用户正常浏览的普通页面,又要存在后台管理系统布局的页面)