数据库为什么要使用索引?
首先说下全表扫描,存储的最小单位是块或页,整个表就是多个块或页,我要进行查找操作就必须将所有的块或页加载进内存,然后一个一个的去查找,这样效率低下。所以我们引入索引。
举个例子,数据库就是一个字典,全表查找就是一页一页的去查找,而索引就是通过拼音首字母就去查找,这样就极大的提高了效率。
什么字段适合做索引?
在mysql中,一般主键就是非常合适的索引,但其他像唯一键,普通键也适合做索引。
确定了索引之后,我们需要以数据结构的形式存放索引,来达到最好的查询效率。
试一下几种不同数据结构作为索引结构的效率
平衡二叉树查找树
特点:节点含有关键字,每一个节点的左子树的值小于它本身,右子树的值大于它本身。
左右子树的树高差小于等于1.
它开始可以达到O(logn)的效率,但是当对数据进行操作之后,如果之后添加的数据一直在树的一边,就会形成这种线性二叉树,使效率变成O(n).
B树
b树的特点:
1.根节点至少包括两个孩子。
2.每个节点至多有m个孩子(m>=2)。
3.除根节点和叶子节点以外,其他每个节点至少有m/2个孩子。
4.所有叶子节点都位于同一层。
5.关键字在树中,自左到右,升序排列。
6.b树将数据存放在非叶子节点中,检索时,可能在任一非叶子节点处结束。
b树由于自身的特点,可以保证树高很低,在检索上,性能不错,是个很好的选择,但是我们有更优的选择B+树。
B+树(mysql索引底层使用)
B+树的特点,它与B的特点差不多,下面是一些区别:
1.非叶子节点与根节点关键字数量相同。
2.指针的值,需要在其指向子树的关键字的区间内。
3.非叶子节点仅储存索引,数据都存储在叶子节点中(这样非叶子节点就可以比B树保存更多的关键字)。
4.所有叶子节点有一个指向下一叶子节点的指针。
根据这些特点,B+树作为索引的优势有:
1.非叶子节点仅仅保存索引,这样一次读入内存中查找的关键字更多,降低了I/O次数。
2.数据都保存在叶子节点中,所以每次查询都要走到叶子节点,也就是每次查询的效率几乎一样
3.每个叶子节点用指针链接起来,这样有利于进行范围查找,提高范围查找的效率。
聚集索引和非聚集索引
聚集索引和非聚集索引的主要区别:
聚集索引:它的B+树的叶子结点包含关键字和其他所有行数据。
非聚集索引:它的B+树的叶子结点只包含关键字和指向行数据的地址。(主键和索引值)
mysql的两种常用引擎的InnoDB使用聚集索引,MyISam使用非聚集索引。
一个表只能创建一个聚集索引,InnoDB在选择聚集索引的过程:
1.如果有主键被定义,那么主键就是聚集索引。
2.若没有主键被定义那么,该表的第一个唯一非空索引作为聚集索引。
3若不满足上面两个条件,InnoDB内部会生成一个隐藏主键(聚集索引)
一个表只能创建一个聚集索引,其他的都是非聚集索引,所有对于InnoDB支持的表的检索过程就是,先通过辅助键索引(非聚集索引)B+树找到主键索引值,再通过主键索引(聚集索引)B+树找到行数据。
聚集索引叶子节点保存的是行数据,而非聚集索引叶子节点保存的只是主键值,这样就好理解为什么要查找两次了。