原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11429438.html

InnoDB默认创建的主键索引是聚簇索引(Clustered Index),其它索引都属于辅助索引(Secondary Index),也被称为二级索引或非聚簇索引。

接下来通过一个简单的例子,说明下这两种索引在存储数据中的具体实现。

首先创建一张商品表,如下:

 CREATE TABLE `merchandise`  (
`id` int(11) NOT NULL,
`serial_no` varchar(20) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`unit_price` decimal(10, 2) DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

然后新增了以下几行数据,如下:

使用的是InnoDB存储引擎,由于InnoDB使用的是聚簇索引,聚簇索引中的叶子节点则记录了主键值、事务id、用于事务和MVCC的回流指针以及所有的剩余列,如下图所示:

基于上面的图示,如果需要根据商品编码serial_no查询商品,就需要将商品编码serial_no列作为一个索引列。此时创建的索引是一个辅助索引,但叶子节点存储的就不是行指针了,而是主键值,并以此来作为指向行的指针。这样的好处就是当行发生移动或者数据分裂时,不用再维护索引的变更。

回表

如果使用主键索引查询商品,则会按照B+树的索引找到对应的叶子节点,直接获取到行数据:

 select * from merchandise where id = 7

如果使用serial_no查询商品,即使用辅助索引进行查询,则会先检索辅助索引中的B+树的serial_no,找到对应的叶子节点,获取主键值,然后再通过聚簇索引中的B+树检索到对应的叶子节点,然后获取整行数据。这个过程叫做回表。

回表就是先通过辅助索引扫描出数据所在的行,再通过行主键id取出索引中未提供的数据,即基于非主键索引的查询需要多扫描一棵索引树。

覆盖索引

假设只需要查询商品的名称、价格信息,有什么方式来避免回表呢?可以建立一个组合索引,即商品编码、名称、价格作为一个组合索引。如果索引中存在这些数据,查询将不会再次检索主键索引,从而避免回表。

从辅助索引中查询得到记录,而不需要通过聚簇索引查询获得,MySQL中将其称为覆盖索引。使用覆盖索引的好处很明显,不需要查询出包含整行记录的所有信息,因此可以减少大量的I/O操作。

通常在InnoDB中,除了查询部分字段可以使用覆盖索引来优化查询性能之外,统计数量也会用到。例如, SELECT COUNT(*)时,如果不存在辅助索引,此时会通过查询聚簇索引来统计行数,如果此时正好存在一个辅助索引,则会通过查询辅助索引来统计行数,减少I/O操作。

 CREATE TABLE `test` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`a` varchar(32) NOT NULL,
`b` varchar(32) NOT NULL,
`c` varchar(64) NOT NULL,
`d` varchar(128) NOT NULL,
`e` varchar(256) NOT NULL,
`create_time` timestamp(3) NOT NULL DEFAULT current_timestamp(3),
`update_time` timestamp(3) NOT NULL DEFAULT current_timestamp(3) ON UPDATE current_timestamp(3),
PRIMARY KEY (`id`),
KEY `idx_a_b` (`a`,`b`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4;

Reference

https://time.geekbang.org/column/article/116369

https://zhuanlan.zhihu.com/p/27700617

InnoDB索引存储结构的更多相关文章

  1. 一文搞懂InnoDB索引存储结构

    参考资料:掘金小册:MySQL 是怎样运行的:从根儿上理解 MySQL B+树 我们知道,InnoDB是用B+树作为组织数据形式的数据结构.不论是存放用户记录的数据页,还是存放目录项记录的数据页,我们 ...

  2. innodb的存储结构

    如下所示,innodb的存储结构包含:表空间,段,区,页(块),行 innodb存储结构优化的标准是:一个页里面存放的行数越多,其性能越高 表空间:零散页+段 独立表空间存放的是:数据.索引.插入缓冲 ...

  3. InnoDB 逻辑存储结构

    本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/80 如果创建表时没有显示的定义主键,mysql会按如下方式创建主 ...

  4. MySQL InnoDB 逻辑存储结构

    MySQL InnoDB 逻辑存储结构 从InnoDB存储引擎的逻辑结构看,所有数据都被逻辑地存放在一个空间内,称为表空间,而表空间由段(sengment).区(extent).页(page)组成.p ...

  5. MYSQL Innodb逻辑存储结构

    转载于网络 这几天在读<MySQL技术内幕 InnoDB存储引擎>,对 Innodb逻辑存储结构有了些了解,顺便也记录一下: 从InnoDB存储引擎的逻辑存储结构看,所有数据都被逻辑地存放 ...

  6. Innodb页面存储结构-2

    上一篇<Innodb页面存储结构-1>介绍了Innodb页面存储的总体结构,本文会介绍页面的详细内容,主要包括页头.页尾和记录的详细格式. 学习数据结构时都说程序等于数据结构+算法,而在i ...

  7. InnoDB逻辑存储结构

    从InnoDB存储引擎的逻辑存储结构看,所有数据都被逻辑地存放在一个空间中,称之为表空间(tablespace).表空间又由段(segment).区(extent).页(page)组成.页在一些文档中 ...

  8. InnoDB表存储结构及keyring加密

    ibdata是InnoDB最重要的系统表空间文件,它记录了InnoDB的核心信息,包括事务系统信息.元数据信息,记录InnoDB change buffer的btree,防止数据损坏的double w ...

  9. sql server 索引阐述系列二 索引存储结构

    一.概述. "流光容易把人抛,红了樱桃,绿了芭蕉“ 转眼又年中了,感叹生命的有限,知识的无限.在后续讨论索引之前,先来了解下索引和表数据的内部结构,这一节将介绍页的存储,页分配单元类型,区的 ...

随机推荐

  1. windows下zookeeper单机版安装+dubbo-admin安装注意点

    一:zookeeper安装 安转包下载地址:http://www.apache.org/dyn/closer.cgi/zookeeper 复制修改conf下的zoo_sample.cfg为zoo.cf ...

  2. https 配置

    参考:https://www.cnblogs.com/tanghuachun/p/9951849.html 1.将pfx文件拷贝到application.properties同级目录下 2.添加配置文 ...

  3. Python3解leetcode Lowest Common Ancestor of a Binary Search Tree

    问题描述: Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in ...

  4. Codeforces 803F - Coprime Subsequences(数论)

    原题链接:http://codeforces.com/contest/803/problem/F 题意:若gcd(a1, a2, a3,...,an)=1则认为这n个数是互质的.求集合a中,元素互质的 ...

  5. Appium运行报错:No Chromedriver found that can automate Chrome '39.0.0'

    运行appium切换webview时候遇到报错:’No Chromedriver found that can automate Chrome 'xx.xx.xx' 此报错是因为Appium在运行过程 ...

  6. PHP之面向对象小结

    PHP 中创建对象 类创建后,我们可以使用 new 运算符来实例化该类的对象: $runoob = new Site; PHP 构造函数 构造函数 ,是一种特殊的方法.主要用来在创建对象时初始化对象, ...

  7. error C2065: ‘_bstr_t’ : undeclared identifier

    转自VC错误:http://www.vcerror.com/?p=828 问题描述: error C2065: '_bstr_t' : undeclared identifier 解决方法: 详细的解 ...

  8. 103、Linux 编译 Kaldi 语音识别工具

    由于这个开源的语音识别工具Kaldi只能在Linux下面成功编译, 所以这一小节来写如何成功地在Linux下面编译Kaldi工具 (1)第一步,去github 上面把 Kaldi下载下来 git cl ...

  9. 抓包工具fiddler下载配置(一):下载/安装&信任证书

    简介 Fiddler一个http协议调试代理工具,它能够记录并检查所有你的电脑和互联网之间的http通讯,设置断点,查看所有的“进出”Fiddler的数据(指cookie,html,js,css等文件 ...

  10. java--二叉树解析及基本实现

    一.二叉树的结构 在进行链表结构开发的过程之中,会发现所有的数据按照首尾相连的状态进行保存,那么 在进行数据查询时为了判断数据是否存在,这种情况下它所面对的时间复杂度就是"O(n)" ...