MySQL索引机制详解(B+树)

1、索引是什么?

  索引是为了加速对表中数据行的检索而建立的一种分散存储的数据结构。mysql

2、为何要使用索引?

  1. 索引能极大的减小存储引擎须要扫描的数据量。
  2. 索引能够把随机IO变成顺序IO。
  3. 索引能够帮助咱们在进行分组、排序等操做时,避免使用临时表。

3、索引是什么实现的?

  Indexes是第三方公司提供的可插拔的插件式存储引擎。sql

  MySQL结构体系:数据库

              

 4、为何选用B+树?

  一、Hash索引方式

            

   缺点:数据结构

  • 利用Hash存储的话须要将全部的数据文件添加到内存,比较耗费内存空间。
  • 若是全部的查询都是等职查询,那么hash确实很快,可是在企业或者实际工做环境中的范围查找的数据更多,并且不是等值查询,所以Hash就不适合了。

  二、二叉树、红黑树索引方式

            

   缺点:性能

  • 太深:数据处的高/深度决定着他的IO操做次数, IO操做耗时大。应先把数据读取效率。
  • 过小:每个磁盘块(节点/页)保存的数据量过小了。

  三、B树(B-树)的索引方式

  

  缺点:

  • B树的每一个节点既有key又有data,可是每一个页存储的空间是有限的,若是data较大的话,那么会致使每一个节点存储的key数量变小。
  • 当存储的数据量很大的时候会致使深度较大,增大查询时候的磁盘IO次数,影响查询性能。
  • Mysql查询的时候使用到了大量的范围查找,B树在性能上并不能知足大量范围查找。

  

  B+Tree与B-Tree的区别:

  • B+节点关键字搜索采用闭合区间。(MYSQL推崇使用ID做为索引,因为ID是自增的数字类型,只会增大,因此采用向右拓展的一个方式。)
  • B+非叶节点不保存数据相关信息, 只保存关键字和子节点的引用。
  • B+关键字对应的数据保存在叶子节点中。
  • B+叶子节点是顺序排列的, 而且相邻节点具备顺序引用的关系。

  选择B+Tree优势:

  • B+树是B-树的变种( PLUS版) 多路绝对平衡查找树, 他拥有B-树的优点。
  • B+树的叶子节点是顺序排列的,且相邻接点具备顺序引用关系,所以在范围查找时扫库、 表能力更强,同时排序能力更强。
  • B+树仅仅在叶子节点存储数据,这样索引文件更小,磁盘读写能力更强。
  • B+树的树高较低,索引文件较小,IO次数稳定,查询效率更加稳定。

5、B+树的索引实现方式

  查看数据存储位置:优化

show variables like 'datadir';

  一、MyIsam

  索引和数据分别存储。表定义存在.frm文件中(每一个存储引擎都会有)。表中数据存在.MYD文件中。索引存在.MYI文件中。spa

            

  若是同一张表多个索引:插件

          

  每一个索引都存有每条数据的地址,一旦有变,维护起来比较耗时。 3d

  二、InnoDB

            

  数据就存在索引的叶子节点中。
  辅助索引:code

            

   其余索引存主键,再从主键索引中找数据。

  注意:

  • InnoDB是经过B+树结构对主键建立索引,而后叶子节点中储存记录,若是没有主键,那么会选择惟一键,若是没有惟一键,那么会生成一个6位的row_id来做为主键。
  • 若是建立索引的键是其余字段,那么在叶子节点中存储的是该记录的主键,而后再经过主键索引找到对应的记录。  

6、索引注意事项

  一、联合索引列选择原则

  • 常常用的列优先 【 最左匹配原则】
  • 选择性( 离散度) 高的列优先【 离散度高原则】(列的离散性越高,选择性就越好。)
  • 宽度小的列优先【 最少空间原则】

  二、覆盖索引

  若是查询列可经过索引节点中的关键字直接返回, 则该索引称之为覆盖索引。

  覆盖索引可减小数据库IO, 将随机IO变为顺序IO, 可提升查询性能。

  好比建立索引:

create index idx_name_phoneNum on users(name,phoneNum);

  查询语句:

select name,phoneNum from user where name=?

  可直接从索引树中返回关键字,不会再去查数据内容。

  三、其余注意事项

  1. 索引列的数据长度能少则少。
  2. 索引必定不是越多越好, 越全越好, 必定是建合适的。
  3. 匹配列前缀可能用到索引 like 9999%, like %9999%、 like %9999用不到索引。like 9999%得看状况,若是索引列离散性高,就能用到索引,离散性低,就用不到索引。
  4. Where 条件中 not in 和 <>操做没法使用索引。
  5. 匹配范围值, order by 也可用到索引。
  6. 多用指定列查询, 只返回本身想到的数据列, 少用select * 以减小IO。
  7. 联合索引中若是不是按照索引最左列开始查找, 没法使用索引。在执行常量等值查询时,改变索引列的顺序并不会更改explain的执行结果,由于mysql底层优化器会进行优化,可是推荐按照索引顺序列编写sql语句。
  8. 联合索引中精确匹配最左前列并范围匹配另一列能够用到索引。(索引列为name,age的话,name=‘zhangsan’ and age>20)
  9. 联合索引中若是查询中有某个列的范围查询, 则其右边的全部列都没法使用索引。(索引列为age,name的话,age>20 and name=‘zhangsan’)

附:B+树添加和删除数据图解 (请放大查看)

相关文章
相关标签/搜索