【MySQL】——MySQL的索引原理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fjj15732621696/article/details/82718102

什么是索引

  • 在MySQL中,索引(index)又叫做键(key),它是存储引擎用于快速找到所需记录的一种数据结构。
  • 在越来越大的表中,索引是对查询性能优化最有效的手段,索引对性能影响非常关键。
  • MySQL的索引是在存储引擎层实现

索引的分类

InnoDB主键使用的是聚簇索引,MyISAM不管是主键索引,还是二级索引使用的都是非聚簇索引。

区别

聚簇索引和非聚簇索引

  • 对于非聚簇索引来说(右图),表数据和索引是分成两个部分存储的,主键索引和二级索引存储上没有任何区别。使用B+树作为索引的存储结构,所有的节点都是索引,叶子节点存储的是索引+索引对应的记录的地址。

  • 对应聚簇索引表来说(左图),表数据是和主键一起存储的,主键索引的叶节点存储行数据(包含主键值),二级索引的叶节点存储行的主键值。使用的是B+树作为索引存储结构,非叶子节点都是索引关键字,但非叶子节点中关键字不存储对应记录的具体内容和内容地址。叶子节点上的数据是主键与具体记录(数据内容)

    聚簇索引的优点
  • 当你需要取出一定范围的数据是,采用聚簇索引好

  • 当通过聚簇索引查找目标数据理论上比非聚簇索引要快,因为非聚簇索引定位到对应主键需要多一次目标记录寻址,即多一次IO

    聚簇索引的缺点
  • 插入速度严重依赖于插入顺序,按照主键的顺序插入是最快的方式,否则将会出现页分裂,严重影响性能。因此,对于InnoDB表,我们一般都会定义一个自增的ID列为主键。

  • 更新主键的代价很高,因为将会导致被更新的行移动。因此,对于InnoDB表,我们一般定义主键为不可更新。

  • 二级索引访问需要两次索引查找,第一次找到主键值,第二次根据主键值找到行数据。

  • 采用聚簇索引插入新值比采用非聚簇索引插入新值的速度要慢很多,因为插入要保证主键不能重复,判断主键不能重复,采用的方式在不同的索引下面会有很大的性能差距,聚簇索引遍历所有的叶子节点,非聚簇索引也判断所有的叶子节点,但是聚簇索引的叶子节点除了带有主键还有记录值,记录的大小往往比主键要大的多。这样就会导致聚簇索引在判定新记录携带的主键是否重复时进行昂贵的I/O代价。

索引种类

单列索引

一个索引只包含单个列,但一个表中可以有多个单列索引。 这里不要搞混淆了。

  • 普通索引:MySQL中基本索引类型,没有什么限制,允许在定义索引的列中插入重复值和空值,纯粹为了查询数据更快一点。
  • 唯一索引:索引列中的值必须是唯一的,但是允许为空值
  • 主键索引:是一种特殊的唯一索引,不允许有空值。(主键约束,就是一个主键索引)
组合索引

在表中的多个字段组合上创建的索引,在使用索引进行查询的时候,要注意索引优化的策略需要使用
索引优化

全文索引

只有在MyISAM引擎上才能使用,只能在CHAR,VARCHAR,TEXT类型字段上使用全文索引,介绍了要求,说说什么是全文索引,就是在一堆文字中,通过其中的某个关键字等,就能找到该字段所属的记录行

空间索引

空间索引是对空间数据类型的字段建立的索引,MySQL中的空间数据类型有四种,GEOMETRY、POINT、LINESTRING、POLYGON。在创建空间索引时,使用SPATIAL关键字。要求,引擎为MyISAM,创建空间索引的列,必须将其声明为NOT NULL。可能跟游戏开发有关。

索引原理分析

二叉查找树

二叉查找树

  • 左子树所有的节点的值小于他的根节点的值,右子树所有的节点的值大于根节点的值
  • 任意节点的左子树和右子树都是二叉查找树
  • 没有键值相等的节点
  • 没有办法减少IO的次数,也就是不能降低树的高度
B-树

B-树
每个节点占用一个盘块的磁盘空间,一个节点上有两个升序排序的关键字和三个指向子树根节点的指针,指针存储的是子节点所在磁盘块的地址。两个关键词划分成的三个范围域对应三个指针指向的子树的数据的范围域。以根节点为例,关键字为17和35,P1指针指向的子树的数据范围为小于17,P2指针指向的子树的数据范围为17~35,P3指针指向的子树的数据范围为大于35。

B+树

B+树
B+Tree是在B-Tree基础上的一种优化,使其更适合实现外存储索引结构,InnoDB存储引擎就是用B+Tree实现其索引结构。
从上一节中的B-Tree结构图中可以看到每个节点中不仅包含数据的key值,还有data值。而每一个页的存储空间是有限的,如果data数据较大时将会导致每个节点(即一个页)能存储的key的数量很小,当存储的数据量很大时同样会导致B-Tree的深度较大,增大查询时的磁盘I/O次数,进而影响查询效率。在B+Tree中,所有数据记录节点都是按照键值大小顺序存放在同一层的叶子节点上,而非叶子节点上只存储key值信息,这样可以大大加大每个节点存储的key值数量,降低B+Tree的高度。

B-树和B+树对比
  • 非叶子节点只存储键值信息
  • 所有叶子节点之间有一个链指针
  • 数据记录都存放在叶子节点中。

    总结

  • 索引是一种数据,可以避免了全表查询,可以类比目录和书。

  • 索引需要一种数据结构来存储
  • 利用散列表(hash)的方式查询复杂度可以到O(1),但是再范围查询时,hash起不了提高性能的作用
  • IO操作是耗时,为了提高查询性能,可以减少IO的次数
  • 对于树的存储结构来说,为了提高性能,减少IO的次数,可以低树的高度
  • 读取一个节点一次IO,在数据量一样的情况下,如果每个节点的能存放更多元素,那么就可以降低树的高度。
  • B树降低了树的高度,而在节点大小一样的情况下,因为B树的节点存放了元素有又存放了数据,而B+树将数据全部存放在叶节点,那么这样的话,每个节点可以存放更多的元素,那么就可以再一次降低树的高度
  • B+树的查询性能更加稳定,并且更有利于范围查找
  • 如果是聚集索引(InnoDB引擎),那么节点存放的该记录的数据,数据文件本身就是索引文件
  • 如果是非聚集索引(MyISAM引擎),那么节点存放的是该行记录的地址。索引文件和数据文件是分离

那些列适合建索引

  • 经常作为查询条件的列
  • 经常作为排序条件的列
  • 经常作为join条件的列

那些列不适合索引

  • 频繁修改的列
  • 区分度不高的列,如性别
  • 不经常作为查询条件,排序条件,连接的列

索引优缺点

  • 正确使用的情况下,索引能提高查询速度
  • 索引也能提高分组和排序速度
  • 由于修改删除添加时,要维护索引文件,对树进行调整,索引性能就降低了
  • 索引文件需要占用空间。

猜你喜欢

转载自blog.csdn.net/fjj15732621696/article/details/82718102