一、为什么需要索引?

大家都知道,我们读取数据时要避免全表扫描,那如何避免全表扫描呢?目前科学家给出的目标就是索引。索引就好比一本字典的目录一样,有了目录读者就不需要翻找全书来找内容。同样有了索引,数据库就不用全表扫描了。

在一张数据表中不管你建不建索引都会有一个默认索引。如果有主键,则mysql会自动按照主键建索引。如果没有主键,mysql也会创建一个默认索引。所以:

在创建表的时候,一定要创建主键。

二、为什么索引存储在硬盘之中呢?

索引是存储在硬盘之中的,这是为什么呢,大家想一下,如果出现意外情况(如:断电),那索引就全没了。所以索引是一定要存储在硬盘上的。但是存在硬盘上有一定的缺陷:性能的降低。

大家知道硬盘的读写速度是远不如内存的,如果频繁的读写硬盘索引,那性能将会非常的低。

三、探索如何提高表的读取速度?

如何提高表的查询速度呢?折半查找是一个好办法,它的时间复杂度是O(log2n),这里我举个例子,我们对数列(5,12,15,27,34,77,89)创造出来的二分查找树如下图所示:

mySQL每个表中都要有一个主键 每个表必须有主键索引_mySQL每个表中都要有一个主键

这是我组建的一棵平衡二叉树,查找效果比较理想,但是也有不理想的情况,比如下面二种情况:

mySQL每个表中都要有一个主键 每个表必须有主键索引_innodb_02


像这样二种情况,查找效率就低非常多了,时间复杂度是O(n)。

像第一种平衡二叉树在mysql中也有很大的不足之处:随着表中数据的增加,二叉树的深度将会非常大,这样导致查找的次数非常多,上面我们提到索引是存储在硬盘上的,如果树的深度太大的话,性能将会非常的低下。

针对二叉树的这种缺点,科学家们引进了多叉树,如下面场景:

mySQL每个表中都要有一个主键 每个表必须有主键索引_B+ tree_03


多叉树的优点就是极大的减少了树的深度,我们下面要讲的B+和B树就是多叉树。

四、B/B-树介绍

B树 英文名是Balance Tree, 全名是平衡多路搜索树。B树的结构图如下:

mySQL每个表中都要有一个主键 每个表必须有主键索引_B tree_04


这里的B树,我不可能画太多数据,只能给大家看看大体样子。3层深度的B树大约能存储100万的数据。深度减少能极大的减少磁盘读取次数,虽然每个节点比较次数不少,但是如果把每个节点的数据读到内存中比较,那这个比较时间就可以忽略不计了。所以用B树来存储对MySQL来说是非常合适的。

B树有以下特点:

1.所有键值分布在整颗树中(索引值和具体data都在每个节点里);
2.任何一个关键字出现且只出现在一个结点中;
3.搜索有可能在非叶子结点结束(最好情况O(1)就能找到数据);
4.在关键字全集内做一次查找,性能逼近二分查找;
5.所有叶子节点位于同一层。

五、B+树介绍

B+树是B树的升级版,结构图如下:

mySQL每个表中都要有一个主键 每个表必须有主键索引_B+ tree_05


B+树相对于B树有以下特点:

1.所有关键字都会在在叶子节点出现,
2.内部节点(非叶子节点)不存储数据,数据只在叶子节点存储
3.所有叶子结点构成了一个链指针,而且说有的叶子节点按照顺序排列。

那B+树比B树有什么优势呢?

1.每一层更宽,更胖,存储的数据更多。因为B+树只存储关键字,而不存储多余data.所以B+树的每一层相比B树能存储更多节点。
2.所有的节点都会在叶子节点上出现,查询效率更稳定。因为B+树节点上没有数据,所以要查询数据就必须到叶子节点上,所以查询效率比B树稳定。而在 B 树中,非叶子节点也会存储数据,这样就会造成查询效率不稳定的情况,有时候访问到了非叶子节点就可以找到关键字,而有时需要访问到叶子节点才能找到关键字。
3.查询效率比B树高。因为B+树更矮,更胖,所以和磁盘交互的次数比B树更少,而且B+树通过底部的链表也可以完成遍历,但是B树需要找到每个节点才能遍历,所以B+树效率更高。

总体来说,B+树因为更矮更胖能存储更多数据、效率稳定,读写磁盘次数少,比B-树效率更高,据统计,一棵深度为3的B+树能存储2000万以上条数据。所以最终选择了B+树。