后端面经系列-索引

后端面经系列-索引

August 6, 2023
后端开发, 数据库
mysql, 数据库
本文中的问题来自极客时间的《后端工程师的高阶面经》 ,答案为本人的理解,仅供阅读者参考。 这门课还是非常不错的,虽然知识不一定完全准确,但是对于复习总结来说,绝对是一个好的大纲,推荐大家购买。

什么是覆盖索引? #

索引中包含所有查询要读取的列,称为覆盖索引。 注意,这里的“所有查询要读取的列”是指查询要读取的列、要用到的列,而不仅仅是select的列,也可能是order by的列、group by的列等。

什么是聚簇索引/非聚簇索引? #

符合以下条件的索引称为聚簇索引:

  • 叶子节点存储的是完整的数据记录。
  • 数据页和记录按照主键值进行排序。

非聚簇索引:

  • 索引中只包含索引键和主键值,不包含全部数据。

什么是哈希索引?MySQL InnoDB引擎怎么创建一个哈希索引? #

  • 哈希索引是指使用哈希算法的索引,使用索引列的hash值作为索引值。
  • 哈希索引只能进行等值查询,不适合进行范围查询。
  • where条件中包含所有索引列时才能使用到哈希索引。

InnoDB引擎不支持hash索引。

什么是回表?如何避免回表? #

回表是指在使用二级索引进行查询后,需要再根据主键id到聚簇索引中查询。

避免回表的方法是:使用覆盖索引。

树的高度和查询性能是什么关系? #

树的高度越低,查询性能越高。

什么是索引的最左匹配原则? #

最左匹配原则,是指mysql在使用联合索引查询时,会从联合索引最左边的列开始进行匹配,直到遇到范围查询(比如<、>、between、like)为止。

范围查询、Like之类的查询怎么影响数据库使用索引? #

影响如下:

  • 可能会导致扫描范围过大,进而导致索引失效。

索引是不是越多越好? #

索引不是越多越好,索引过多可能会导致:

  • 占用过多的磁盘空间。每个索引中除了存储索引列的值外,还会存储主键列的值,用于回表,索引越多,占用的磁盘空间越大。
  • 更新数据时,需要更新索引,索引越多,更新索引的代价越大。
  • 查询优化器需要选择合适的索引,索引越多,查询优化器在选择索引时的工作量越大,耗时越久。
  • 索引越多,在更新数据时,可能会导致死锁及锁等待超时。

使用索引有什么代价? #

  • 占用磁盘空间。
  • 运行时,占用内存空间。
  • 更新数据时,需要更新索引,更新、删除、写入性能下降。

如何选择合适的索引列?组合索引里面怎么确定列的顺序?状态类的列是否适合作为索引的列? #

怎么选择合适的索引列:

  • 选择区分度高的列作为索引列。

组合索引里面怎么确定列的顺序:

  • 尽可能将区分度高的列放在前面。需要注意order by的顺序。

状态类的列一般区基数太小、区分度不高,不适合作为索引的列。

为什么 MySQL 使用 B+ 树作为索引的数据结构?为什么不用 B 树?为什么不用红黑树?为什么不用二叉平衡树?为什么不用跳表? #

  • B+树的非叶子节点不存储数据,可以存储更多的索引,树的高度更低,在查找时可以减少磁盘IO次数。
  • B树的非叶子节点存储数据,不能进行范围查询。
  • 平衡二叉树、红黑树的缺陷:高度比B+树高,查找时需要更多的磁盘IO,效率更低;为了保持平衡,会频繁进行再平衡,性能更差;
  • 跳表在极端情况下会退化为链表,平衡性差。

NULL 对索引有什么影响? #

  • 唯一二级索引中可能有多个null值。
  • 值为null的记录排在最左侧。
  • 使用is null和is not null 就不会使用到索引的说法不准确。

唯一索引是否允许多个 NULL 值? #

允许。