八股P1-MySQL索引

132 阅读6分钟

什么是索引?

索引是一种用于快速查询和检索数据的数据结构,其本质可以看成是一种排序好的数据结构。

索引的优缺点?

优:

  • 大大加快数据的检索速度、大大减少检索的数据量
  • 创建唯一索引,可以保证数据库表中每行数据的唯一性

缺:

  • 创建、维护索引耗费时间。如果数据有索引,增删改时,索引也要动态修改,降低SQL效率。
  • 索引用物理文件存储耗费一定空间

索引底层数据结构有哪些?为什么用B+树不用其他?

Hash 表

哈希表是键值对的集合,通过键(key)即可快速取出对应的值(value),可以快速检索数据(时间复杂度接近 O(1))

1.为何能够通过 key 快速取出 value 呢?  

原因在于 哈希算法。通过哈希算法,我们可以快速找到 key 对应的 index,也就找到了对应的 value。

image.png

2.什么是Hash 冲突,怎么解决?

  • 经哈希算法后,多个不同的 key 最后得到的 index 相同。
  • 常用链地址法解决。将哈希冲突数据存放在链表中。JDK1.8 之前HashMap通过链地址法来解决,JDK1.8以后引入了红黑树。为了减少链表过长导致搜索时间过长

优:查询速度快

缺:不支持顺序和范围查询

B 树& B+树

B 树也称B- 树,全称为 多路平衡查找树 ,B+树是B树的一种变体。B树和B+树中的B是Balanced(平衡)的意思。

目前大部分数据库系统及文件系统都采用 B-Tree 或其变种 B+Tree 作为索引结构。

B 树& B+树两者有何异同呢?

  • B+ 树只有叶子节点放 key 和 data,内部节点只放 key。B 树的所有节点既放key,也放data
  • B+ 树叶子节点加入链表指针,指向与它相邻的叶子节点。B 树叶子节点都是独立
  • B+ 树的检索效率稳定任何查找都是从根节点到叶子节点的过程,且叶子节点的顺序检索很明显。 B 树检索的过程,相当于对范围内每个节点的关键字做二分查找,可能还没有到达叶子节点,检索就结束了
  • B+ 树的范围查询,只需遍历链表即可。B 树进行范围查询时,先找到要查找的下限,然后对 B 树进行中序遍历直到找到查找的上限

综上,B+树 与 B 树相比,具备更少的IO次数、更稳定的查询效率和更适于范围查询这些优势。

在 MySQL 中,MyISAM 引擎和 InnoDB 引擎都是使用 B+Tree 作为索引结构,但是,两者的实现方式不太一样

MyISAM 引擎

  • B+Tree 叶子节点的 data 域存放数据的地址
  • 非聚簇索引,索引结构和数据分开存放的索引

InnoDB 引擎

  • B+Tree 叶子节点的 data 域存放数据
  • 聚簇索引,索引结构和数据一起存放的索引。表数据和主键一起存储
  • 主键索引的叶子节点,存数据(包含主键值)
  • 其他的索引叫二级索引(辅助索引)叶子节点,存主键值
    • 根据主索引搜索时,直接找到 key 所在的叶子节点即可取出数据;根据辅助索引查找时,则先取出主键的值,再走一遍主索引。
    • 不建议使用过长的字段作为主键,也不建议使用非单调的字段作为主键,这样会造成主索引频繁分裂。

索引分类/有哪些索引?

按数据结构维度分:

  • BTree 索引:MySQL 里默认和最常用的索引类型。
  • 哈希索引:类似键值对的形式,一次即可定位。
  • RTree 索引:一般不会使用,仅支持 geometry 数据类型,优势在于范围查找,效率较低,通常使用搜索引擎如 ElasticSearch 代替。
  • 全文索引:对文本的内容进行分词、搜索。目前只有 CHARVARCHARTEXT 列上可以创建全文索引。一般不会使用,效率较低,通常使用搜索引擎如 ElasticSearch 代替。

按存储方式分:

  • 聚簇索引索引结构和数据一起存放的索引,InnoDB 中的主键索引就属于聚簇索引。
  • 非聚簇索引索引结构和数据分开存放的索引,二级索引(辅助索引)就属于非聚簇索引。MySQL 的 MyISAM 引擎,不管主键还是非主键,使用的都是非聚簇索引。

按应用维度分:

  • 主键索引加速查询 + 列值唯一(不可以有 NULL)+ 表中只有一个
  • 普通索引:仅加速查询。
  • 唯一索引加速查询 + 列值唯一(可以有 NULL)+ 可以有多个
  • 覆盖索引:一个索引包含(覆盖)所有需要查询的字段的值。
  • 联合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并。
  • 全文索引:对文本的内容进行分词,进行搜索。目前只有 CHARVARCHARTEXT 列上可以创建全文索引。一般不会使用,效率较低,通常使用搜索引擎如 ElasticSearch 代替。

聚簇索引与非聚簇索引

聚簇索引

索引结构和数据一起存放的索引。InnoDB 中的主键索引就属于聚簇索引。

InnoDB 引擎表来说,B+树的每个非叶子节点存储索引叶子节点存储索引和索引对应的数据

优点

  • 查询速度非常快:相比于非聚簇索引, 聚簇索引少了一次读取数据的 IO 操作。
  • 对排序查找和范围查找优化

缺点

  • 依赖于有序的数据:如果索引的数据不是有序的,在插入时排序,如果数据是字符串或 UUID 这种速度很慢。
  • 更新代价大:主键索引来说,主键一般不可修改

非聚簇索引

索引结构和数据分开存放的索引。二级索引(辅助索引)属于非聚簇索引。MySQL 的 MyISAM 引擎,不管主键还是非主键,使用的都是非聚簇索引。

非聚簇索引的叶子节点可以存地址指针,也可以存主键。因为二级索引的叶子节点就存放的是主键,根据主键再回表查数据。

优点

更新代价小 :非聚簇索引的叶子节点是不存放数据的

缺点

  • 依赖于有序的数据:跟聚簇索引一样,非聚簇索引也依赖于有序的数据
  • 可能会二次查询(回表) :这应该是非聚簇索引最大的缺点了。 当查到索引对应的指针或主键后,可能还需要根据指针或主键再到数据文件或表中查询。