索引分类:
按物理存储分类:聚簇索引(主键索引)、二级索引(辅助索引)
按字段特性分类:主键索引,普通索引,唯一索引,前缀索引
按字段个数分类:单列索引,联合索引
主键索引:拿主键当作索引,
普通索引:除主键之外的字段当做索引
二级索引:除主键之外的字段被查询时,就是二级索引
覆盖索引:从非主键索引中就能查到记录,不需要查询主键索引,减少了树的搜索次数,显著提升性能。主键索引B+树存储的是整行数据,而普通索引B+树存储的是该索引字段数据和主键id。如果要查询的数据通过二级索引能查的出来,就不用回表再通过主键索引去查了,只用一个B+Tree就能找到数据。
联合索引:将多个字段组合成一个索引,多个字段值作为B+的key值,遵循最左匹配原则,如果不遵循索引就会失效。
联合索引的最左匹配原则,在遇到范围查询(如 >、=、<) 的时候,就会停止匹配,也就是范围查询的字段可以用到联合索引,但是在范围查询字段的后面的字段无法用到联合索引。注意,对于>=、<=、between、like 前缀匹配的范围查询,并不会停止匹配。
InnoDB数据结构选择B+Tree 的原因:
B+Tree相比BTree,B树只在叶子树节点存放数据,而B树在非叶子树节点也要存放数据,相较于B树,B+树单个节点的数据两更小,在相同的I/O次数下,就能查询更多节点。而且B树叶子节点采用的双链表连接,适合Mysql中常见的基于范围的查找,B树无法做到这一点。
B+相比Hash,Hash找明确的值非常快,但是mysql很多都是范围查找,不适用Hash
B+相比二叉树,二叉树一个节点只能有两个子节点,所以其搜索复杂度为log2N,但是B+搜索复杂度为logdN,d是子节点的数量,这会比二叉树检索速度快很多。
索引优化:
前缀索引优化:适用于一些大字符串的字段,使用前缀索引可以减少索引项的大小。order by 无法使用前缀索引
覆盖索引优化:不需要查询出包含整行记录的所有信息,减少了很多回表的操作,也减少了I/O操作
主键索引最好自增:B+是按照主键顺序存放的,如果主键值是随机的,会出现主键值插入到现有数据中间页的情况,此时还需要移动其他的数据,有可能还要从一个页面复制数据到另一个页面(页分裂),影响查询效率。
主键字段长度不要太大,会影响二级索引占用的空间
防止索引失效:
- 左右模糊匹配会失效
- 查询条件中对索引列做了计算、函数、类型转换等操作
- 不遵循最左匹配原则
- where子句中,在OR前的列是索引列,OR后的列不是索引列,则会失效。