MySQL二级索引的查询过程
聚簇索引就是innodb默认创建的基于主键的索引结构,而且表里的数据就是直接放在聚簇索引里,作为叶节点的数据页:
基于主键的数据搜索:从聚簇索引的根节点开始进行二分查找,一路找到对应数据页,基于页目录就直接定位到主键目标数据。
若想对其它字段建立索引,甚至是基于多个字段建立联合索引,此时索引结构又是咋样?
假设对其他字段建立索引,如name、age之类,都是一样原理。比如你插入数据时:
- 把完整数据插入聚簇索引的叶节点的数据页,同时维护好聚簇索引
- 为你其他字段建立的索引,重新再建立一颗B+树
比如你基于name字段建立了一个索引,当插入数据时,就会重新搞一颗B+树,B+树的叶节点也是数据页,但该数据页里仅放主键字段和name字段:
这是独立于聚簇索引之外的另一个name字段的B+索引树,其叶节点的数据页仅存放主键和name字段值。
整体排序规则都跟聚簇索引按照主键的排序规则是一样,即:
- 叶节点的数据页中的name值都是排序的
- 下一个数据页里的name字段值都>上一个数据页里的name字段值
name字段的索引B+树也会构建多层级的索引页,索引页里存放:
- 下一层的页号
- 最小name字段值,根据name字段值排序。
所以若你根据name字段查数据,过程也一样,从name索引树的根节点开始,一层一层往下找,一直找到叶节点的数据页,定位到name字段值对应的主键值。
然后针对
select * from t where name='xx'
这种语句,先根据name值在name索引树里找,找到叶节点,也仅能找到对应主键值,而找不到这行数据的所有字段。
所以还需回表:还需根据主键值,再到聚簇索引里从根节点开始,找到叶节点的数据页,定位到主键值对应的完整数据行,此时才能把select *
要的全部字段值都取出。
联合索引
比如name+age,运行流程同理,建立一个独立的B+树,叶节点的数据页存放id+name+age后,默认按name排序,name一样就按age排,不同数据页之间的name+age值的排序也如此。
然后这个name+age的联合索引的B+树的索引页存放:
- 下一层节点的页号
- 最小的name+age的值
所以当你根据name+age搜索时,就会走name+age联合索引树,搜索到主键,再根据主键到聚簇索引里去搜索。
总结
以上就是InnoDB索引的实现原理,就是建立B+树,层层二分查找。不同的索引就是建立了不同B+树,然后增删改时:
- 在数据页里更新数据
- 维护你所有的索引
相关文章
- mysql索引总结(4)-MySQL索引失效的几种情况
- mysql索引总结(3)-MySQL聚簇索引和非聚簇索引
- mysql的慢查询实战+sql优化
- mysql服务器参数
- mysql中json_replace函数的使用?通过json_replace对json对象的值进行替换
- 测试环境治理之MYSQL索引优化篇
- 有趣的 Mysql 存储引擎
- MySQL 5.6的72个新特性(译)
- MySQL进阶篇(02):索引体系划分,B-Tree结构说明
- 数据库表设计时一对一关系存在的必要性 数据库一对一、一对多、多对多设计 面试逻辑题3.31 sql server 查询某个表被哪些存储过程调用 DataTable根据字段去重 .Net Core Cors中间件解析 分析MySQL中哪些情况下数据库索引会失效
- Mysql为表字段添加索引
- MySQL如何确定VARCHAR大小
- Mysql数据库一个表字段中存了id,并以逗号分隔,id对应的详细信息在另一个表中
- MySQL查看/修改/删除索引
- Mysql的索引介绍
- 九、Mysql - 错误日志 - 慢日志 - 通用日志 - 二进制日志 - undolog - redolog - 事务的执行过程
- mysql 索引
- MySQL 优化之 MRR (Multi-Range Read:二级索引合并回表)
- MySQL 优化之 ICP (index condition pushdown:索引条件下推)
- 如何高效高性能的选择使用 MySQL 索引?
- MySQL中的一些非常实用的函数、语法
- 行成于思:从Oracle到MySQL
- Linux下的Mysql的双向同步
- MYSQL PERFORMANCE_SCHEMA HINTS
- [Spark][Python]Spark 访问 mysql , 生成 dataframe 的例子:
- (4.2)mysql备份还原——备份概述
- MySQL索引背后的数据结构及算法原理--转
- mysql 索引长度和区分度
- mysql性能优化-慢查询分析、优化索引和配置
- 由浅入深探究mysql索引结构原理、性能分析与优化
- MySQL 服务无法启动