[1] 现状
按照不同的分类规则,各种索引的归属情况如下:
其中,有些索引是解释一下就可以明白的,然而有些索引很容易混淆,比如主键索引和聚集索引是同一个东西吗?
[2] 单列索引、组合索引
· 单列索引:只在一个列上的索引被称作单列索引。一个表可以有多个单列索引,但这不是组合索引。
· 组合索引:两个或更多个列上的索引被称作组合索引,组合索引又叫联合索引。
单列索引与组合索引有哪些区别?
1、组合索引具有最左前缀原则,创建组合索引时,要考虑列的顺序,例如A,B两个字段都会在查询中用到,但A使用的频率更高,就将A作为组合索引的第一个字段,放在最左边。
2、组合索引具有最左前缀原则,在写where查询时,如果一次使用组合索引的左侧列查询,组合索引有效,直接使用后几列查询,组合索引无效。
第2点不展开,可以去搜索“最左前缀原则”。
3、当存在多个单列索引可以用时,mysql会根据查询优化策略选择其中一个单列索引,并不是每个单列索引都生效。
4、当同时存在单列索引和组合索引,mysql会根据查询优化策略选择其中一个索引。
5、如果where中的关系是or,索引不生效。
单列索引与组合索引有哪个效率更高?
如果我们的查询where条件只有一个,我们完全可以用单列索引,这样的查询速度较
快。如果我们的业务场景是需要经常查询多个组合列,不要试图分别基于单个列建立多个单列索引(因为虽然有多个单列索引,但是MySQL只能用到其中的那个它认为似乎最有效率
的单列索引)。这是因为当SQL语句所查询的列,全部都出现在组合索引中时,此时由于只需要查询索引块即可获得所有数据,当然比使用多个单列索引要快得多。
[3] 主键索引、唯一索引、普通索引、前缀索引
· 主键索引:是在唯一索引的基础上又增加了不为空的约束(换言之,添加了唯一索引的字段,是可以包含NULL
值的),即NOT NULL+UNIQUE
,一张表里最多只有一个主键索引,当然一个主键索引中可以包含多个字段。
· 唯一索引:是在普通索引的基础上增加了数据唯一性的约束,一张表中可以同时存在多个唯一索引。
· 普通索引:是最基础的索引,这种索引没有任何的约束作用,它存在的主要意义就是提高查询效率。
· 前缀索引:前缀索引也叫局部索引,比如给身份证的前 10 位添加索引,类似这种给某列部分信息添加索引的方式叫做前缀索引。
为什么要用前缀索引?
前缀索引能有效减小索引文件的大小,让每个索引页可以保存更多的索引值,从而提高了索引查询的速度。但前缀索引也有它的缺点,不能在 order by 或者 group by 中触发前缀索引,也不能把它们用于覆盖索引。
什么情况下适合使用前缀索引?
当字符串本身可能比较长,而且前几个字符就开始不相同,适合使用前缀索引;相反情况下不适合使用前缀索引,我们需要继续加大前缀字符的长度,但是这个时候前缀索引的优势已经不明显,就没有创建前缀索引的必要了。
[4] 聚集索引、非聚集索引
按照物理实现方式,索引可以分为两大类:
· 聚集索引:在聚集索引里,表中数据行按索引的排序方式进行存储,对查找行很有效。只有当表包含聚集索引时,表内的数据行才会按找索引列的值在磁盘上进行物理排序和存储。每张表只能有一个聚集索引,原因很简单,因为数据行本身只能按一个顺序存储。
· 非聚集索引:非聚集索引也称为二级索引或者辅助索引,对于非聚集索引,数据库会有单独的存储空间来存放。非聚集索引在查找的时候要经过两个步骤,需要先搜索非聚集索引的B+Tree
,这个B+Tree
的叶子结点存储的不是完整的数据行,而是主键值,当我们搜索完成后得到主键的值,然后拿着主键值再去搜索主键索引的B+Tree
,就可以获取到一行完整的数据。
⭐⭐主键索引就是聚集索引吗?
不是。 当我们基于 InnoDB 引擎创建一张表的时候,都会创建一个聚集索引,每张表都有唯一的聚集索引:
1、如果这张表定义了主键索引,那么这个主键索引就作为聚集索引。
2、如果这张表没有定义主键索引,那么该表的第一个唯一非空索引作为聚集索引。
3、如果这张表也没有唯一非空索引,那么 InnoDB 内部会生成一个隐藏的主键作为聚集索引,这个隐藏的主键是一个 6 个字节的列,该列的值会随着数据的插入自增。
对于一张表来说,聚集索引只能有一个,因为数据真实的物理存储顺序就是按照聚集索引存储的。主键是表中的一个字段或多个字段,用来唯一地标识表中的一条记录。唯一性是主键最主要的特性。主键的创建必须依赖于索引,默认创建的是聚集索引。
聚集索引的注意事项?
聚集索引在插入的时候,最好是主键自增,自增主键插入的时候比较快,直接插入即可,不会涉及到叶子节点分裂等问题(不需要挪动其他记录);而其他非自增主键插入的时候,可能要插入到两个已有的数据中间,就有可能导致叶子节点分裂等问题,插入效率低(要挪动其他记录)。如果聚集索引在插入的时候不是自增主键,插入效率就会比较低。所以像一些UUID主键和一些乱序主键还是要避免使用的。
[5] 全文索引
全文索引是将存储在数据库中的整本书或整篇文章中的任意内容信息查找出来的技术。它可以根据需要获取全文中有关章,节,段,句,词等信息,也可以进行各种统计和分析。
之前的MySQL数据库中,INNODB存储引擎并不支持全文索引技术,大多数的用户转向MyISAM存储引擎,不过这可能进行表的拆分,并需要将进行全文索引的数据存储为MyIsam表。这样的确能够解决逻辑业务的需求,但是却丧失了INNODB存储引擎的事务性,而这在生产环境应用中同样是非常关键的。
从INNODB1.2.x版本开始,INNODB存储引擎开始支持全文索引,其支持myisam的全部功能,并且还支持其他的一些特性。
[6] 覆盖索引
覆盖索引是select的数据列只用从索引中就能够取得,不必读取数据行,换句话说查询列要被所建的索引覆盖。
也就是说,发生了覆盖索引,就不会有回表查询。
索引是高效找到行的一个方法,但是一般数据库也能使用索引找到一个列的数据,因此它不必读取整个行。毕竟索引叶子节点存储了它们索引的数据;当能通过读取索引就可以得到想要的数据,那就不需要读取行了。一个索引包含了(或覆盖了)满足查询结果的数据就叫做覆盖索引。