数据库索引详解
MySQL索引中使用的数据结构主要有B+索引和哈希索引。
因此 当绝大多数需求为单挑记录查询时 可以选择哈希索引 因为其查询性能最好,其余的大多数场景选择B+索引。B+索引对于MyISAM和InnoDB的实现方式是不同的。
MyISAM用的时 非聚簇索引。因为其B+ tree叶节点域存放的时数据记录的地址,在索引检索中,首先按照B+tree搜索算法搜索索引,如果指定的key存在 则取出地址 找到data记录。
InnoDB用的是 聚簇索引 就是数据文件本身就是索引文件,因此相比于MyISAM(索引文件和数据文件是分离的),其表数据文件本身就是按照B+ tree组织的一个索引结构。树的叶节点的data域完整的保存了数据记录。这个索引的key为表的pk。此外同一张表还会存在辅助索引,这种索引与MyISAM也不同 其data域储存相应的记录逐渐的值而并非地址。总结一下 就是利用pk进行搜索时,直接找到key所在节点直接取出数据。在根据辅助索引查找时 先取出主键的值再走一遍主索引。因此在表的设计时 不要用很长的字段作为主键(因为所有的辅助索引都引用主索引 如果主索引过长 那么辅助索引文件就会非常大),也不建议用非单调字段作为主键(因为InnoDB数据文件本身是一颗B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效)。
上面的介绍会对索引有一些基本的理解 下面我们从底层开始看一下:
首先我们来看一下B-和B+ tree
B树比2-3树还要肥
B-树的特性:
1.关键字集合分布在整颗树中;
2.任何一个关键字出现且只出现在一个结点中;
3.搜索有可能在非叶子结点结束;
4.其搜索性能等价于在关键字全集内做一次二分查找;
5.自动层次控制;
B+树是由B-树衍生过来的
与B-Tree相比,B+Tree有以下不同点:
1.非叶子结点的子树指针与关键字个数相同;
2.非叶子结点的子树指针P[i],指向关键字值属于[K[i], K[i+1])的子树(B-树是开区间);
3.为所有叶子结点增加一个链指针;
4.所有关键字都在叶子结点出现;
5.内节点不存储data,只存储key
索引:
索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。
这样的话,索引查找过程中就要产生磁盘I/O消耗,而我们在优化的时候 就要使索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数。
我们执行算法是在内存里,所以在用B-树查找文件的时候 只会在磁盘中储存的索引树中定位,然后将对应的数据导入内存中。具体过程详见:https://www.jianshu.com/p/1775b4ff123a
而对于B+树 相对于B-树有以下优点:
- B+树磁盘读写代价更低:举个例子,假设磁盘中的一个盘块容纳16bytes,而一个关键字2bytes,一个关键字具体信息指针2bytes。一棵9阶B-tree(一个结点最多8个关键字)的内部结点需要2个盘快。而****B+树内部结点只需要1个盘快(因为B+树不需要储存内部指针)。当需要把内部结点读入内存中的时候,B-树就比B+ ****树多一次盘块查找时间(在磁盘中就是盘片旋转的时间)。
- B+树查询效率更加稳定(毕竟所有的数据都在叶结点中)
B+树在两种数据库引擎中的不同实现:(MyISAM和InnoDB的主索引和辅助索引)
MyISAM用B+树作为索引结构,叶节点data域存放的使数据记录的地址。在MyISAM中 主索引和辅助索引结构上相同,只是pk和fk的不同而已。
因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。与MyISAM不同 InnoDB的辅助索引和主索引不同,辅助索引data域储存响应记录主键的值而不是地址。所以在利用辅助索引搜索的时候 首先检索索引获得主键的值 再用主键到主索引中检索获得记录。

浙公网安备 33010602011771号