一:什么是索引?
所谓索引,就相当于目录。比如我们的新华字典,如果要找哪个字,一定会先找目录,通过目录再找到具体的目标。众所周知,数据库也是按页进行存储的。那么数据库一样可以通过类似新华字典一样设计,维护一个目录,而该目录,就是我们的数据库索引
二:索引的分类(从数据结构角度)
1.hash索引
hash索引的单条记录的查询效率是非常高的,通过hashmap可知,hash索引的时间复杂度是O(1),数据库引擎会为每一行记录计算几个hash值,然后数据库引擎会维护该hash码,但是因为值相近的两个数据,hash值也会相差很远,所以hash索引只适合精确查找(InnoDB是不支持hash索引的)
2.b+树索引
先简要概括一下b+树的特点
(1)数据只存放在叶子节点,非叶子节点只存储key信息(与b树重要的区别之一,即稳定又快,因为数据只放在叶子节点,每次都只需要遍历叶子节点即可)
(2)叶子节点的数据是有序的
(3)叶子节点之间是一个有序链表
三:B+树索引的结构
了解完B+树特点,再来了解一下b+树索引结构
1.主键索引类型
(1)索引页(有两种索引页,对应B+树中的非叶子节点)
①主键-数据页目录:用来存储主键与数据页的信息,也就是数据页对应的最小主键
②主键-索引页目录:当数据太多时,为了避免主键目录太重,非叶子节点也可以存储主键与索引页的信息,也就是索引页对应的最小主键
(2)数据页:顾名思义就是用来存储数据的节点,也就是树的叶子节点
通过主键索引的查询数据的流程:根据主键找到索引页,再根据索引页找到数据页,进而在数据页中找到目标数据
2.非主键索引:主键索引与非主键索引原理基本都是一样的(索引会按照一定的值进行排序)
首先一样会使用b+树维护索引,索引页依然是类似的,索引对应的索引页或数据页。但是数据页与主键索引不同,主键索引的数据页是主键+对应的整条记录;而非主键索引则是索引+主键(索引有可能是复合索引)。那么通过非主键索引查询数据的流程是怎么样的呢?
(1)查询的内容是索引内容,直接走索引,然后返回对应的目录内容
(2)查询的内容不是索引内容:走索引,然后找到对应的主键,然后再去维护主键的b+树,通过主键找出对应的数据,这个过程也叫做回表
另外:数据库表若没有显示设置索引,默认主键就是索引,若没有主键,数据库也会默认使用表的rowid为索引。
最后,知道了索引原理,也就知道了为什么说添加索引会耗费空间,甚至性能的原因了(需要维护整棵b+树!!!)
四:添加索引以及索引使用条件
1.添加索引
(1)在建表时创建:添加索引约束即可
(2)在已存在的表中创建:
①create [type] index index_name on table(column)
②alter table table_name add [type] index index_name (column)
2.索引使用注意
(1)索引字段要单独出现:如 select * from student where id = 1;
(2)like查询不能以通配符开头,但是可以通配符结尾,否则无法走索引
(3)单索引查询时,复合索引只对第一个字段有效(复合查询适用于复合查询,即使用多个索引查询的查询)
(4)or 两边条件都需要用到索引,有一边无索引都不会走索引
五:从物理存储上看索引类型
从物理存储上看索引,有两大类型,分别是聚簇索引与非聚簇索引。两者的根本区别是索引的逻辑顺序与数据存放的物理顺序是否一致。对于聚簇索引来说,索引的逻辑顺序与数据存放的物理顺序是一致的,也就是说,如果索引相邻,则数据在磁盘上的位置也是相邻的(因为叶子节点存的是数据,可以理解为索引优先,索引的顺序决定数据在磁盘上的数据)。所以聚簇索引会影响数据在表中的位置(数据存放的位置需要参考索引的位置,可能与表中的物理位置不一样,只有使用自增的主键索引才会与表中的物理位置一样)。对于非聚簇索引来说,索引的顺序与数据在磁盘的位置是不一致的(因为叶子结点存的是数据行的地址或主键,如普通索引,即索引相邻,记录在磁盘上的地址不一定相邻,即索引的顺序与记录在磁盘上的顺序没有关系)