index.md

·interview-questions

MySQL为什么使用B+树来作索引? 说一下索引失效的场景?

Q:建立索引要注意哪些问题

A:首先是要明确好热点查询,只针对真正会用到且查询频率高的字段建立索引,避免过多的索引导致性能下降;其次是要考虑索引的选择性,选择性越高的字段越适合做索引,选择性低的字段做索引反而会降低性能;另外是要考虑索引的存储空间和维护成本,索引会占用额外的存储空间,并且在数据更新时也需要维护索引,所以要权衡好性能和存储空间之间的关系;最后是要定期检查和优化索引,删除不必要的索引,避免冗余和重复的索引

Q:性别和年龄要不要建立索引,以及记录的如果是初中生的年龄,还要不要建立索引

A:其实都没什么必要,因为性别和年龄的选择性都比较低,性别只有男和女两个值,年龄也只有特定数量的值,所以做索引的话反而会增加存储空间和维护成本,而且查询性能提升也不明显;如果是初中生的年龄,那就更没必要了,因为初中生的年龄范围也就 12 到 15 岁,只有四个值,做索引的话反而会降低性能,因为索引页命中后还要回表,除非是业务确实有这个需求,那可以把年龄放到联合索引的末尾,但其实这样也不会提升特别多性能,不如用缓存或者分区表来优化

Q:是不是有索引就一定会走,优化器选择走索引的边界值是多少

A:不是的,是否走索引是由优化器的代价比较决定的,优化器会估算全表扫描的顺序读成本和索引查找 + 回表的随机读成本,然后选择代价更低的方案;边界值的话其实并不是固定的,常用的经验法则是当索引筛出的行数小于总行数的 3% - 5% 时索引扫描通常更优,否则全表扫描更划算,但这也不是绝对的,因为有很多参数都影响着优化器的选择,在实际开发中可以使用 explain 和 analyze 来观察优化器行为来判断是否使用了索引

Q:按照种类讲一下 MySQL 的索引

A:按数据结构有 B+ 树索引、哈希索引和全文索引,按物理存储有聚簇索引和二级索引,按字段特性有主键索引、唯一索引、普通索引、前缀索引、单列索引和联合索引,B+ 树索引是最常用的索引类型,支持范围查询和模糊查询,哈希索引适合等值查询但不支持范围查询,全文索引适合对大文本字段的全文检索;聚簇索引是数据存储的顺序和索引的顺序一致,二级索引则是数据存储和索引存储分离;主键索引是唯一且非空的索引,唯一索引是唯一但可以为空的索引,普通索引是非唯一的索引,前缀索引是只对前 N 个字符建立索引,单列索引是对单个字段建立的索引,联合索引是对多个字段联合建立的索引

Q:MySQL 建表会使用到哪些索引

A:在建表时我会先给表定义一个自增主键做聚簇索引,保证行存和主键一致,如果业务需要保证某列数据唯一,就加唯一索引,对于常用的过滤和连接字段,我会建普通索引来防止全表扫描,如果多个字段经常一起作为条件,我会用最左前缀建立联合索引,并尽量做覆盖索引来减少回表;如果有大文本字段需要做全文检索,我会使用全文索引来加速查询

Q:联合索引在匹配的时候要考虑什么

A:首先要遵循最左前缀原则,查询必须从最左边的字段开始才能使用索引,并且只有等值条件才能继续往后匹配,遇到范围查询则会截止,另外要把选择性高的列放在最前面,避免在索引列上使用函数或隐式转换,否则都会导致不能走索引,如果要进一步提高性能,可以设计成覆盖索引,让查询完全在索引层面完成而不用回表

  • 有用过联合索引吗,就是多个字段建一个索引

  • 那比如说你要在一张表上去加一个索引,这个会比较快吗,还是其实挺慢的,你有没有试过,就是说加索引的这个动作本身,不是说加索引的效果,相当于对表结构做变更嘛,我需要加一个索引

  • 假如说现在有一个表它现在需要加索引,它加索引的耗时跟哪些因素有关系?跟硬件的哪些因素会有关系吗?

  • 比如说我们在加这个索引或者做别的 DDL 的时候,我们对现有业务可能带来什么样的风险呢?

  • 具体是用哪条命令来看索引有没有命中

  • 能说一下 MySQL 在建立联合索引的一些注意事项吗,比如说索引的一些列有什么样的规则或规范,比如在建立联合索引时哪些列应该列入到联合索引里,哪些列又不应该列到联合索引里面

  • 我建了五个列的联合索引,这样的联合索引对于我的读和写有哪些影响

  • 联合索引建的太多对于写的影响是什么