加载八叉树索引文件_mysql innodb索引原理
聚集索引(clustered index)
innodb存储引擎表是索引组织表,表中数据按照主键顺序存放。其聚集索引就是按照每张表的主键顺序构造一颗B+树,其叶子结点中存放的就是整张表的行记录数据,这些叶子节点成为数据页。
聚集索引的存储并不是物理上连续的,而是逻辑上连续的,叶子结点间按照主键顺序排序,通过双向链表连接。多数情况下,查询优化器倾向于采用聚集索引,因为聚集索引能在叶子结点直接找到数据,并且因为定义了数据的逻辑顺序,能特别快的访问针对范围值的查询。
聚集索引的这个特性决定了索引组织表中的数据也是索引的一部分。由于表里的数据只能按照一颗B+树排序,因此一张表只能有一个聚簇索引。
在Innodb中,聚簇索引默认就是主键索引。如果没有主键,则按照下列规则来建聚簇索引:
- 没有主键时,会用一个非空并且唯一的索引列做为主键,成为此表的聚簇索引;
- 如果没有这样的索引,InnoDB会隐式定义一个主键来作为聚簇索引。
由于主键使用了聚簇索引,如果主键是自增id,那么对应的数据也会相邻地存放在磁盘上,写入性能较高。如果是uuid等字符串形式,频繁的插入会使innodb频繁地移动磁盘块,写入性能就比较低了。
B+树(多路平衡查找树)
我们知道了innodb引擎索引使用了B+树结构,那么为什么不是其他类型树结构,例如二叉树呢?
计算机在存储数据的时候,有最小存储单元,这就好比人民币流通最小单位是分一样。文件系统的最小单元是块,一个块的大小是4k(这个值根据系统不同并且可设置),InnoDB存储引擎也有自己的最小储存单元—页(Page),一个页的大小是16K(这个值也是可设置的)。
文件系统中一个文件大小只有1个字节,但不得不占磁盘上4KB的空间。同理,innodb的所有数据文件的大小始终都是16384(16k)的整数倍。
所以在MySQL中,存放索引的一个块节点占16k,mysql每次IO操作会利用系统的预读能力一次加载16K。这样,如果这一个节点只放1个索引值是非常浪费的,因为一次IO只能获取一个索引值,所以不能使用二叉树。
B+树是多路查找树,一个节点能放n个值,n = 16K / 每个索引值的大小。
例如索引字段大小1Kb,这时候每个节点能放的索引值理论上是16个,这种情况下,二叉树一次IO只能加载一个索引值,而B+树则能加载16个。
B+树的路数为n+1,n是每个节点存在的值数量,例如每个节点存放16个值,那么这棵树就是17路。
从这里也能看出,B+树节点可存储多个值,所以B+树索引并不能找到一个给定键值的具体行。B+树只能找到存放数据行的具体页,然后把页读入到内存中,再在内存中查找指定的数据。
附:B树和B+树的区别在于,B+树的非叶子结点只包含导航信息,不包含实际的值,所有的叶子结点和相连的节点使用链表相连,便于区间查找和遍历。
辅助索引
也称为非聚集索引,其叶子节点不包含行记录的全部数据,叶子结点除了包含键值以外,每个叶子结点中的索引行还包含一个书签,该书签就是相应行的聚集索引键。
如下图可以表示辅助索引和聚集索引的关系(图片源自网络,看大概意思即可):
当通过辅助索引来寻找数据时,innodb存储引擎会通过辅助索引叶子节点获得只想主键索引的主键,既然后再通过主键索引找到完整的行记录。
例如在一棵高度为3的辅助索引树中查找数据,那需要对这颗辅助索引树进行3次IO找到指定主键,如果聚集索引树的高度同样为3,那么还需要对聚集索引树进行3次查找,最终找到一个完整的行数据所在的页,因此一共需要6次IO访问来得到最终的数据页。
创建的索引,如联合索引、唯一索引等,都属于非聚簇索引。
联合索引
联合索引是指对表上的多个列进行索引。联合索引也是一颗B+树,不同的是联合索引的键值数量不是1,而是大于等于2。
例如有user表,字段为id,age,name,现发现如下两条sql使用频率最多:
Select * from user where age = ? ;Select * from user where age = ? and name = ?;
这时候不需要为age和name单独建两个索引,只需要建如下一个联合索引即可:
create index idx_age_name on user(age, name)
联合索引的另一个好处已经对第二个键值进行了排序处理,有时候可以避免多一次的排序操作。
覆盖索引
覆盖索引,即从辅助索引中就可以得到查询所需要的所有字段值,而不需要查询聚集索引中的记录。覆盖索引的好处是辅助索引不包含整行记录的所有信息,故其大小要远小于聚集索引,因此可以减少大量的IO操作。
例如上面有联合索引(age,name),如果如下:
select age,name from user where age=?
就能使用覆盖索引了。
覆盖索引的另一个好处是对于统计问题,例如:
select count(*) from user
innodb存储引擎并不会选择通过查询聚集索引来进行统计。由于user表上还有辅助索引,而辅助索引远小于聚集索引,选择辅助索引可以减少IO操作。
注意事项
- 索引只建合适的,不建多余的
因为每当增删数据时,B+树都要进行调整,如果建立多个索引,多个B+树都要进行调整,而树越多、结构越庞大,这个调整越是耗时耗资源。如果减少了这些不必要的索引,磁盘的使用率可能会大大降低。
- 索引列的数据长度能少则少。
索引数据长度越小,每个块中存储的索引数量越多,一次IO获取的值更多。
- 匹配列前缀可用到索引 like 9999%,like %9999%、like %9999用不到索引;
- Where 条件中in和or可以使用索引, not in 和 <>操作无法使用索引;
如果是not in或<>,面对B+树,引擎根本不知道应该从哪个节点入手。
- 匹配范围值,order by 也可用到索引;
- 多用指定列查询,只返回自己想到的数据列,少用select *;
不需要查询无用字段,并且不使用*可能还会命中覆盖索引哦;
- 联合索引中如果不是按照索引最左列开始查找,无法使用索引;
最左匹配原则;
- 联合索引中精确匹配最左前列并范围匹配另外一列可以用到索引;
- 联合索引中如果查询中有某个列的范围查询,则其右边的所有列都无法使用索
作者:信~仰
加载八叉树索引文件_mysql innodb索引原理相关推荐
- mysql的索引文件_MySQL:索引在磁盘上的存储
一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上.这样的话,索引查找过程中就要产生磁盘I/O消耗,相对于内存存取,I/O存取的消耗要高几个数量级,所以评价一个 ...
- 加载八叉树索引文件_这篇 MySQL 索引和 B+Tree 讲的太通俗易懂!
正确的创建合适的索引,是提升数据库查询性能的基础.在正式讲解之前,对后面举例中使用的表结构先简单看一下: create table user (id bigint not null comment ' ...
- js后退页面不重新加载_快应用:支持加载单独JS文件的规范思考
当前快应用的项目中,支持加载其它JS文件(通过:require('./foo.js')),然后通过webpack工具处理依赖,最终完成页面JS的构建,其中页面JS包含了引入的所有JS内容: 本文讨论的 ...
- xBIM 实战01 在浏览器中加载IFC模型文件
系列目录 [已更新最新开发文章,点击查看详细] 一.创建Web项目 打开VS,新建Web项目,选择 .NET Framework 4.5 选择一个空的项目 新建完成后,项目结构如下: 二.添 ...
- spark-submit --files 动态加载外部资源文件
在做spark时,有些时候需要加载资源文件,需要在driver或者worker端访问.在client模式下可以使用IO流直接读取,但是在cluster模式下却不能直接读取,需要如下代码: val is ...
- uiwebview 读取本地html,UIWebView加载本地HTML文件
一.准备HTML文件及其资源文件 使用UIWebView加载本地的HTML文件 index.html,在index.html中引用了本地的图片.CSS文件.JS文件以及外部的图片. index.htm ...
- ajax如何请求json文件,简单的ajax请求加载外部json文件
我在学习ajax ....我试图从json文件发出一个基本请求,它与我的index.html位于同一个文件夹中,但由于某种原因它说未定义:(我可以看到错误是可变的人,但我不能赶上为什么它未定义.... ...
- pygame加载中文名mp3文件出现error
好一阵子没有写东西了,最近几天在做一个基于Python pygame的音乐播放器,本来想做完了,再来发篇文章的,可越做越深,框架大致出来了,考虑周期比较长,也可能是我个人问题,做得比较慢.下面来谈谈p ...
- Android中使用WebChromeClient显示Openlayers加载本地GeoJson文件显示地图(跨域问题解决)
场景 Openlayers中加载GeoJson文件显示地图: Openlayers中加载GeoJson文件显示地图_BADAO_LIUMANG_QIZHI的博客-CSDN博客 上面加载显示GeoJso ...
- SpringBoot+Mybatis加载Mapper.xml文件的两种方式
前言:我们在平常工作中用到mybatis去加载Mapper.xml文件,可能mapper文件放的路径不一样,由此我们需要配置多个路径,幸运的是Mybatis支持我们配置多个不同路径.现在介绍两种方法. ...
最新文章
- Spring Boot 整合 Freemarker
- Web API 简单示例
- 1~9组成三个3位的平方数
- vue怎么传数据给后台_千万日活级产品人必备:数据监控后台之数据指标怎么选?...
- php addall,深入解析thinkphp中的addAll方法
- Linux Crontab内环境变量与Shell环境变量的关系及解决问题的办法
- 使用Python写入docx文件并控制字体颜色
- 最近30分钟合约市场爆仓702万美元 BTC爆仓281万美元
- 对Moss 2007中访问群体的设置和使用补充
- ssh的mysql分页查询_在SSH框架下按条件分页查询
- 教师个人计算机研修总结,计算机研修总结
- 北京邮电大学计算机学院合并,北京邮电大学院系重组
- win7禁用显示方向旋转快捷键
- lol8月21号服务器维护,lol维护到几点今天?英雄联盟LOL8月21日维护更新内容
- java中string长度有限制吗,最大是多少?
- linux系统调用:exit()与_exit()函数详解【转】
- 文化传播有限公司网站源码dian
- LM小型可编程控制器软件(基于CoDeSys)笔记四:如何用rs232下载plc程序
- 广和通L610 4G模块MQTT连接阿里云物理模型
- unity3d 直接播放mp3
热门文章
- LVM报错:resize2fs: Bad magic number in super-block
- 百度官方wormHole后门检测记录(转)
- 使用AT指令给飞信号发短信失败
- mysql的时间类型的比较
- C# windows服务程序中的Timer控件的问题
- 如何记才能不搞混绝对路径和相对路径
- android平台网络命令编程,Android网络编程-Socket
- 18awg线材最大电流_USB4来了,最大的变化是这个
- git分支详细讲解,模拟分支开发,为什么使用分支开发
- okhttp post php,Android OkHttp 结合php 多图片上传实例