联合索引底层数据结构

MySQL可以使用多个字段同时建立一个索引,叫做联合索引。上文中讲到索引的底层结构就是一个二叉树,联合索引也是一样,它的非叶子节点中存的就不只是一个列,是索引的所有列,并且它的排序就是根据索引列的先后顺序来排的。

例如建立了一个(‘name’,‘age’,‘position’)三个列的联合索引,那么非叶子节点中就存储了name,age,position字段,排序的时候先根据第一个字段name来排序,再按第二个字段age排序,再按position字段排序。从左往右,name为H开头的肯定排在b开头的数据后面,name相同的情况下,age=10的肯定排在age=9的后面,以此类推。

那么根据此图,我们就能很好理解联合索引的最左前缀原则了。
以上图为例。 我创建了一个示例表:

CREATE TABLE `test_index` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`age` int(11) DEFAULT NULL,`position` varchar(255) DEFAULT NULL,`update_time` datetime DEFAULT NULL,PRIMARY KEY (`id`),KEY `idx_name_age_position` (`name`,`age`,`position`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
并且已经创建了索引 `idx_name_age_position` (`name`,`age`,`position`)

索引长度计算方法

计算规则
1.索引字段,没有设置NOT NULL,需要占用一个字节。NULL在mysql中是用一个标志位来表示的,用一个字节,null也走索引,并且排在索引的最前面。并不是有些说法说的那样不走索引的
2.定长字段:tinyiny占1个字节、int占4个字节、bitint占8个字节、date占3个字节、datetime占5个字节,char(n)占n个字符。
3.变长字段:varchar(n)占n个字符+2个字节。
4.不同的字符集,一个字符占用的字节数不同:

latin1编码,每个字符占用一个字节
gbk编码,每个字符占用两个字节
utf8编码,每个字符占用三个字节
utf8mb4编码,每个字符占用四个字节

像上面的例子,我用的是utf8编码,并且没有设置不可为null。
name索引长度: 2553+2+1=768 (null标志位占一个字节)
age索引长度:4+1=5 (null标志位占一个字节)
position索引长度: 255
3+2+1=768 (null标志位占一个字节)

联合索引示例

.

  1. explain select * from t where name=‘Bill’ and age=40 and position=‘dev’

    走索引的,并且可以看到索引长度为1541,768+768+5=1541,正好对的上,说明走了这个索引的全部字段。
    我如果把name列改为不可为Null(具体过程就不写了),再来看一下

    key_len变成1540了,说明 null 确实占一个字节。这里只为说明 null 占一个字节,后续的示例都是可以为null情况的。
  2. explain SELECT * FROM test_index where name=‘Bill’ and age>30;

    走索引,并且索引长度为773(768+5)说明走了索引的name,age字段
  3. explain SELECT * FROM test_index where name=‘Bill’ and age>30 and position = ‘dev’;.
    走索引,只走了索引的name,age字段,position字段没走。可以看到索引长度为773(768+5)
    确实走不了position字段这部分,age是一个范围查找,定位到age=30之后,可以根据索引找到>30的记录,但是position索引没法用啊,你不能说age=Bill,age=30,position=dev这条记录的数据右边都是满足条件的,age=31,position=aaa 也是在它右边,是不满足查询要求的。只能对前两个字段用索引
  4. explain SELECT * FROM test_index where name=‘Bill’ and position = ‘dev’;

    走索引,只走了索引的name字段部分,position字段没走,可以看到索引长度为768
  5. explain SELECT * FROM test_index where name=‘Bill’ and position > ‘dev’;.
    走索引,只走了索引的name字段部分,position字段没走,可以看到索引长度为768
  6. explain SELECT * FROM test_index where age=30 and position = ‘dev’;

    不走索引,因为第一列没被引用,那么要想找到 age=30 and position = 'dev’的记录,只能把索引全部扫描一遍,再通过回表去找到对应记录,那还不如全表扫描。
  7. explain SELECT * FROM test_index where name>‘Bill’ and age=30 and position = ‘dev’;
    走索引,只走了索引的name字段部分,age 和 position字段没走,可以看到索引长度为768
    name是范围查找,可以走name那一部分索引

Mysql 联合索引相关推荐

  1. mysql联合索引的数据结构

    一.本文主要讲解的内容有: 联合索引在B+树上的存储结构 联合索引的查找方式 为什么会有最左前缀匹配原则 在分享这篇文章之前,我在网上查了关于MySQL联合索引在B+树上的存储结构这个问题,翻阅了很多 ...

  2. mysql 联合索引详解

    mysql 联合索引详解 联合索引又叫复合索引.对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分.例如索引是key index (a,b,c). ...

  3. 找到符合条件的索引_高频面试题:MySQL联合索引的最左前缀匹配原则

    前言 之前在网上看到过很多关于mysql联合索引最左前缀匹配的文章,自以为就了解了其原理,最近面试时和面试官交流,发现遗漏了些东西,这里自己整理一下这方面的内容. 最左前缀匹配原则 在mysql建立联 ...

  4. mysql联合索引测试

    mysql联合索引和查询条件的匹配原则: 只有当联合索引的第一个字段在where条件中出现时,才会使用索引查询,不然就是全表扫描查询. 表的索引为: KEY `Index_query` (`trans ...

  5. mysql 联合索引 range_MySQL 联合索引使用情况

    验证联合索引使用的情况 索引是一个排序的结构,用于快速检索和加速排序 MySQL表结构 index_test | CREATE TABLE `index_test` ( `c1` char(10) N ...

  6. SQL Server中的联合主键、聚集索引、非聚集索引、mysql 联合索引

    我们都知道在一个表中当需要2列以上才能确定记录的唯一性的时候,就需要用到联合主键,当建立联合主键以后,在查询数据的时候性能就会有很大的提升,不过并不是对联合主键的任何列单独查询的时候性能都会提升,但我 ...

  7. MySQL联合索引以及索引顺序优化

    MySQL联合索引以及索引顺序优化 1. 环境准备 2. 测试验证 1. 环境准备 -- 查看版本 ,5.7.19-17-log select VERSION();-- 创建表结构 CREATE TA ...

  8. 关于MySQL联合索引和优化军规

    一.关于MySQL联合索引 总结记录一下关于在MySQL中使用联合索引的注意事项. 如:索引包含表中每一行的last_name.first_name和dob列,即key(last_name, firs ...

  9. MySQL联合索引原理解析

    什么是MySQL联合索引 联合索引又叫复合索引,是MySQL的InnoDB引擎中的一个索引方式,如果一个系统频繁地使用相同的几个字段查询结果,就可以考虑建立这几个字段的联合索引来提高查询效率. 如何建 ...

  10. mysql联合索引怎么存储_联合索引在B+树上的存储结构及数据查找方式

    能坚持别人不能坚持的,才能拥有别人未曾拥有的. 关注编程大道公众号,让我们一同坚持心中所想,一起成长!! 引言 上一篇文章<MySQL索引那些事>主要讲了MySQL索引的底层原理,且对比了 ...

最新文章

  1. java 过滤器 中文_Java web整站中文过滤器实现
  2. 代理模式(为对象提供相同的接口)
  3. Linemod;理解
  4. iOS开发UI篇—控制器的创建
  5. android消息通知布局,Android Design
  6. python清屏命令-python清屏命令
  7. 服务器项目访问速度,【随心秀】优化1M带宽的云服务器访问速度
  8. 即插即用!Batch Transformer
  9. linux中打开caj文件,Ubuntu20.04使用CAJViewer for Linux(可双击打开.caj文件)
  10. 中职网络安全2022国赛之隐写术应用
  11. php车牌识别,跨平台车牌识别应用 Light-LPR
  12. Study「Photoshop」:勾线图
  13. 多线程 委托 匿名函数 拉姆达 事件
  14. 运维常用命令大全,从入门到精通就靠它了!
  15. 笔记本选购2018.9
  16. 如何有效阅读他人代码(一)
  17. android网络优化,Android性能优化----网络优化
  18. 不止腾讯、阿里, 大厂区块链人才稀缺, 这样的你太珍惜...
  19. 读陈景润之《初等数论》
  20. 解决网页播放【鼠标移开屏幕或点击屏外视频暂停播放】

热门文章

  1. CSS 相对/绝对(relative/absolute)定位系列(二)
  2. 无界Pro只是开始,奇瑞新能源要全面智能化
  3. 面试问题:消息队列使用场景
  4. 计算机既是服务器又是工作站,计算机三级.docx
  5. iOS 自定义转场动画, nav的push/pop自定义动画
  6. python2怎么卸载_mac如何卸载python 2
  7. 四旋翼无人机学习之准备篇(一)
  8. Java简单的生成/解析二维码(zxing qrcode)
  9. 2019区块链的19个预测
  10. 零代码应用搭建规范建议