索引可以提高查询效率,那他到底是如何提高查询效率呢?(面试题)

一.索引是什么?

索引是数据库中用来提高查询效率的技术,类似于目录。如果不使用索引,数据会零散的保存在磁盘块中,查询数据需要挨个遍历每一个磁盘块,直到找到数据为止,使用索引后会将磁盘块以树桩结构保存,查询数据时会大大降低磁盘块的访问数量,从而提高查询效率。如果表中的数据很少,使用索引反而会降低查询效率。并且索引会占用磁盘空间,一般只针对查询时常用的字段创建索引。索引分为聚集索引和非聚集索引,通过主键创建的索引称为聚集索引,聚集索引中保存数据,只要给表添加主键约束,则会自动创建聚集索引;通过非主键字段创建的索引称为非聚集索引,非聚集索引中没有数据。还可以通过多个字段来创建复合索引。

二.MySQL中存储索引用的是什么结构?

MySQL中存储索引用的一般都是B+树。它的数据都存放在叶子节点中,同时叶子节点之间还添加了指针形成了链表。有点像HashMap的底层实现,数组 + 链表的结构。
索引可以提高查询效率,那他到底是如何提高查询效率呢?(面试题)_第1张图片
上图是一个4路B+树,可以清楚的看到,所有的数据都存放在叶子节点上,并且叶子节点之间有指针链表相连。

三.为什么要用B+树?

首先,B+树是平衡树。树的查询效率是log(n),n为树的高度。如果使用非平衡树,如二叉树。那么在特殊情况,如插入的数据是有序的,会出现什么情况呢?
索引可以提高查询效率,那他到底是如何提高查询效率呢?(面试题)_第2张图片
二叉树发生了退化,变成了链表,树的高度变高了,影响了查询的效率。由于B+树是平衡树,保证了树的高度是最优的,所以不会出现上述的退化情况。上文展示了一个4路的B+树,可以看出当路数越多时,树的高度是越低的,那么问题来了,为什么不设计一个无限多路的B树来降低树高度,从而提升查询效率呢?先来看看一个无限多路的B树是什么样的。
索引可以提高查询效率,那他到底是如何提高查询效率呢?(面试题)_第3张图片
不限路数,B树就退化成了一个数组。那么会出现什么问题呢?数据库的索引是存储在硬盘上的,如果数据量大的话,不一定可以一次性加载到内存中。这时候,多路存储的好处就体现出来了,可以每次加载树的一个节点,然后一步步往下找。比如一个三路的B树,每个节点最多有两个数,查找的时候每次载入一个节点进内存就行,就不会出现数据量过大无法加载到内存中的情况。在业务场景中查询数据时,往往是查询多条数据,比如查询最近修改过的10条数据,B+树在B树的基础上进行了优化,B+树的所有数据都在叶子结点,同时有链表结构,只需要找到首尾,就可以把所有的数据找出来了。综上述所述,MySQL中存储索引用B+树的好处主要是降低树高度提高查询效率、多路设计保证硬盘到内存的加载、叶子节点存储数据并且加了指针形成链表在范围查找时只需定位首尾就可以取出所需数据。


为什么能够提高查询速度?

索引就是通过事先排好序,从而在查找时可以应用二分查找等高效率的算法。
一般的顺序查找,复杂度为O(n),而二分查找复杂度为O(log2n)。当n很大时,二者的效率相差及其悬殊。

举个例子:

表中有一百万条数据,需要在其中寻找一条特定id的数据。如果顺序查找,平均需要查找50万条数据。而用二分法,至多不超过20次就能找到。二者的效率差了2.5万倍!

在一个或者一些字段需要频繁用作查询条件,并且表数据较多的时候,创建索引会明显提高查询速度,因为可由全表扫描改成索引扫描。

(无索引时全表扫描也就是要逐条扫描全部记录,直到找完符合条件的,索引扫描可以直接定位)

不管数据表有无索引,首先在SGA的数据缓冲区中查找所需要的数据,如果数据缓冲区中没有需要的数据时,服务器进程才去读磁盘。
1、无索引,直接去读表数据存放的磁盘块,读到数据缓冲区中再查找需要的数据。
2、有索引,先读入索引表,通过索引表直接找到所需数据的物理地址,并把数据读入数据缓冲区中。

索引有什么副作用吗?

(1)索引是有大量数据的时候才建立的,没有大量数据反而会浪费时间,因为索引是使用二叉树建立.

(2)当一个系统查询比较频繁,而新建,修改等操作比较少时,可以创建索引,这样查询的速度会比以前快很多,同时也带来弊端,就是新建或修改等操作时,比没有索引或没有建立覆盖索引时的要慢。

(3)索引并不是越多越好,太多索引会占用很多的索引表空间,甚至比存储一条记录更多。
对于需要频繁新增记录的表,最好不要创建索引,没有索引的表,执行insert、append都很快,有了索引以后,会多一个维护索引的操作,一些大表可能导致insert 速度非常慢

你可能感兴趣的:(索引可以提高查询效率,那他到底是如何提高查询效率呢?(面试题))