MySql索引本质分析
当我们提高查询效率时,从mysql数据库层面来说,往往会我们考虑使用索引来提高效率,然而,为何给表添加索引,就能提高查询效率?
- 什么是索引?
索引是帮助MySQL高效获取排好顺序的数据结构
- 索引的数据结构
- 二叉树
- 红黑树
- Hash表
- B+Tree
数据结构这么多中,MySQL采用什么实现?他们之间有什么区别?
- 先看二叉树存储
- 如上图可以看出,使用二叉树,按上面的数据以及结构最多只需要经过3次磁盘I/O就能找到需要的的数据,如果没有建立索引,查询时将会表头到表尾进行全表扫描,然而使用二叉树是否就没有问题了?我们来看下面的图:
- 可以得出,当使用二叉树时,在最坏情况下,会形成一个单项链表。。。。
- 那如果使用红黑树呢?接下来我们看看红黑树的数据结构进行分析:
- 红黑树,是一个自平衡二叉树,根据红黑树的特性随着数据量的不断增加,树的深度也将会不断的变深,然后磁盘I/O的次数也将取决于树的深度。
- Hash表是如何使用的?hash表记录了每一个索引值对应的hash值指向对应地址,当通过该值查询时,只需要计算出hash值,就能找出该行,这个过程都是在内存中进行的,只需要进过一次磁盘I/O就能实现搜索,使用Hash是否更快呢?使用Hash将会引入一下问题:
- 所有数据加载到内存,将会导致内占用内存过多
- 无法通过范围查询
- 再看看看B+Tree(b-Tree变种)
- 非叶子节点不储存data,只存储索引(冗余),可以存放更多索引
- 叶子节点包含所有索引字段
- 叶子节点用指针连接,提高区间访问的性能
非叶子节点主要是冗余索引,当树高为3时,叶子节点存满的时候,大概可以存2千过万个元素(1170* 1170*16),所以千万条数据使用b+树,最多也只是经过2-3次磁盘I/O,就能查找到元素。
- MySAM索引文件和数据文件是分离的(非聚集索引)
- InnoBD索引实现(聚集)
- 标数据文件本身就是按B+Tree组织的一个索引结构文件
- 聚集索引-叶子节点包含了所有索引和数据记录
- 为什么InnoDB必须有主键,并且推荐使用整形的自增主键?
- 为什么非主键索引结构叶子节点存储的是主键值?(一致性和节省存储空间)