索引到底是什么东西,它又是怎么工作的呢?
索引是对数据库表中一列或多列的值进行排序的结构,使用索引可快速访问数据库表中特定的信息。
索引是为了加速对表中数据行的检索而创建的一种分散存储的数据结构。
索引分为聚集索引和辅助索引。InnoDB存储引擎表是索引组织表,表中数据是按照主键顺序存放。
聚集索引就是按照每张表的主键构造一颗B+树,同时叶子节点中存放的为整张表的行记录数据,因此聚集索引的叶子节点也称为数据页。聚集索引是逻辑连续而不是物理连续:1、页之间通过双向链表连接,页按照主键顺序排序。2、每个页中的记录也是通过双向链表进行维护。
辅助索引,叶子节点不包含行记录的全部数据,包含键值、索引行。索引行中包含了一个书签,书签用来告诉InnoDB存储引擎哪里可以找到与索引相对应的行数据。
现在我们可以搞明白,为什么使用索引比较快。如果使用聚集索引,不用全表扫描,只需根据主键比较,可以直接筛选掉很多数据。如果使用辅助索引,也同理,不过需要多几次逻辑I/O,因为辅助索引中并不存放数据行的所有数据,我们还需要查找聚集索引才能找到需要的数据行。
联合索引
两个或以上列的索引被称为联合索引。联合索引在对第一列排序的基础上再对第二列排序,依此类推。假设我们建立了(a,b,c)这样一个联合索引,相当于建立了a,(a,b),(a,b,c)三个索引。联合索引不支持对b,c进行查找。这是我们俗称的最左匹配原则。
最左匹配原则
最左匹配到底是什么意思呢?联合索引上,数据排序按照联合索引创建时列的顺序依次排序的。
例如联合索引(a,b,c),在a排序的基础上再对b排序最后对c排序。由此我们可以看出当a值确定时b才有序,否则b是无序的。所以直接对b,c进行查找时没有效果。但是可能会对整个索引进行扫描,因为b,c依然是联合索引的一部分,mysql可能会采用index方式扫描整个联合索引,直到找到符合条件的某个索引。
简单的总结下:最左匹配的原理,联合索引会对最左边定义的列排序,再依次对后续列排序。在最左列的值确定后,后续的列才有是有序的。联合索引才有效果。
覆盖索引
解释一: 就是select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖。
解释二: 索引是高效找到行的一个方法,当能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了。如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫 做覆盖索引。
解释三:是非聚集组合索引的一种形式,它包括在查询里的Select、Join和Where子句用到的所有列(即建立索引的字段正好是覆盖查询语句[select子句]与查询条件[Where子句]中所涉及的字段,也即,索引包含了查询正在查找的所有数据)。
回表
先定位主键值,再定位行记录。
如果 select 所需获得列中有大量的非索引列,索引就需要到表中找到相应的列的信息,这就叫回表。
索引下推
Index Condition Pushdown icp
用于联合索引的场景。于mysql 5.6版本之后引入。在5.6之前,根据最左匹配原则,在遇到第一个字段用了模糊查询之后,后续的字段就不能使用该索引,只能回表,存储引擎返回数据给服务器然后再判断数据是否符合条件。
5.6引入索引下推之后,如果存在某些被索引的列的判断条件时,可以在索引遍历过程中,对索引中包含的字段先做判断,过滤掉不符合条件的记录,减少回表次数。
