索引:Mysql建立的用来快速查询的已经排好序的数据结构。
索引的目的就是为了快速查找数据。
Mysql索引使用B+树实现的,B+树是B树的一个变种。
索引的数据结构还可以有其他形式。
哈希表,有序数组,二叉搜索树,红黑树。
哈希表
哈希表就是一种键值对的存储结构,根据哈希函数和键进行运算得到这个值所在的位置,如果发生哈希冲突就在这个位置拉一个链表。
如果哈希函数设计的不好,而数据又是随机的,有可能会出现某一条链表数据很多,数组的其他位置,数据很少,此时哈希表相当于退化成了一个链表。
而且哈希表不适合范围查询,因为哈希表存储是无序的。
二叉树
二叉搜索树的查询复杂度为O(log(N)),但是数据有序的情况下仍然退化成链表。
红黑树解决了退化的问题,但是二叉搜索树和红黑树都有一个相同的问题,就是当遇到海量数据的时候,树的高度太大。每查询一个节点就是一次磁盘IO,仍然有很大的性能损耗。而B-树解决了这个问题。
B树
B树就是一个N叉树。B树在一个节点上存一页数据。即使是海量数据也可以极大的减少树的高度。
B树与B+树的不同只在于B+树把行信息都存放在叶子节点上,而B树每个节点上都有行信息。
B+树的非叶子节点存放的是指向叶子节点的指针。


图中每个叶子节点最多只能存放两个数据。
回表
主键索引树的叶子节点当中存放的是当前行的所有列的信息。
而其他索引树的叶子节点当中存放的是索引列以及主键的信息。
因此如果根据其他索引进行查询的话,而且查询内容是SELECT *,那么MySQL在索引树上找到该索引的位置之后,得到主键的值,再根据这个主键的值,去主键索引树中查询所有的列信息。这一过程就叫做回表,因此除非必要,尽量少写select *。使用非主键索引查询时,很有可能会多查一棵树,因此也尽量使用主键索引。
索引维护
和红黑树二叉搜索树一样,B+树在插入新值的时候也要进行维护,保证其满足B+树的特性。
如果一个节点中的数据以及存满,而新插入的值按照规则需要放入这个节点中,那么就要对这个节点中的数据进行迁移,有可能需要把多出来的数据放入其他节点,或者新申请一个数据页。此时就会影响性能。
因此如果可以尽量使用自增主键,因为自增主键对于索引树来说只有追加操作没有插入操作。比较容易维护。
索引下推
索引下推(ICP),是MySQL在5.6版本时推出的新功能,用于优化查询。
索引下推可以减少回表次数。
例如联合表中有复合索引(name,age)
此时查询
select * from tuser where name like '王%' and age=20 and sex='男';
因为使用了like,所以like之后的索引失效。
如果没有索引下推。
InnoDB会在找到所有以王开头的名字的主键,然后根据主键回表找到所有数据。
若有n个名字以王开头的数据,则需要回表n次。
server层根据age和sex确定最后的数据。
如果有索引下推。
InnoDB会找到所有以王开头的名字的主键,然后会继续在这些数据中筛选符合出age=20的数据的主键,根据主键找到所有记录,然后在server层进行sex=男的筛选。最后得到数据集。
使用了索引下推之后会减少回表的次数,并且会减少返回给server层的数据的量。
网友评论