数据库索引的通俗理解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sundacheng1989/article/details/53117172

最近使用到Oracle数据库的索引比较多,所以就想好好研究一下索引到底是什么。毕竟作为一个Application Developer,而不是DBA,所以这篇文字也是很通俗,特别浅显的描述了一下索引相关的概念。

 

为什么需要索引?数据在磁盘上是以块的形式存储的。为确保对磁盘操作的原子性,访问数据的时候会一并访问所有数据块。磁盘上的这些数据块与链表类似,即它们都包含一个数据段和一个指针,指针指向下一个节点(数据块)的内存地址,而且它们都不需要连续存储(即逻辑上相邻的数据块在物理上可以相隔很远)。

 

举个例子来讲,我们有一个数据表User.为了简便,这个表没有主键。

 

Identity

Name

Age

Grade

1

Robin

28

90

5

Lilei

26

60

3

Hanmei

25

50

4

Lucy

27

66

2

Lily

29

80

 

虽然这些数据都存在于一个User表中,但是物理上,这些数据可能存储在分散的数据块中。

 

查找Lily这个人的信息, 已知LilyIdentity2 select * fromUser where Identity= 2.

 

在查找的时候,首先找到这个表的第一条记录所在的数据库地址,然后发现Identity1,并不是所需要的值,然后在这个数据库的底端,找到了下一个数据块的地址。(这个类似于链表),如此一来,查询了5次才找到了所需要的值。(为了简单起见,我们考虑Identity不能有重复值)

 

为了加快搜索速度,这里就出现了索引。索引是对某个字段进行排序的一种方式。对表中的某个字段建立索引会创建另一种数据结构,其中保存着字段的值,每个值又指向与它相关的记录。这种索引的数据结构是经过排序的,因而可以对其执行二分查找。

 

对上个表的Identity字段进行索引,就是在数据库存储空间上创建一块专用的控件,把User表的所有的Identity字段的值拿出来放到这里,并且对这些值进行排序,并且每个值都携带着这个Identity对应的行所在数据块的地址。因为Identity是进过排序的,按照一定的数据结构存储的,所以数据库引擎在查找的时候,比如说查找identity5,引擎就会计算,5大概在整个排序结构的大致地方,然后到那里去拿出这个值看看是不是,不是的话就再次相应的向左或者向右移动去寻找。(这里用到的知识都是大学时候的数据结构的知识,二分法查找,相对于毫无头绪的一个一个的查找,二分法的查找速度明显的提高,达到了log2 N,其实这有多快我也不明白,反正就记得当时学的时候,确实是比一般查找快多了。)

 

通俗的来讲,就是根据你指定的列,建立一个遵循一定数据结构的区域,这些区域可以快速定位到相应数据库字段所在的磁盘地址。

 

 

索引的好处是特别明显的,那就是大大的提高了查询的速度。但是相对应的也带来了一些不好的地方。


第一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。

第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。

第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。

 

 

最后还有一点需要注意的是,我们在数据库上对于某个字段建立了索引,那么什么情况下才走索引呢?

 

比如 select * from User where Identity= 2 这条语句,是走索引查询的。因为是否走索引取决于这条查询语句的where子句。数据库引擎发现你的where语句中有identity,那么就会从identity的索引数据结构中进行检索。曾经看到有人说select *会降低检索速度,这个跟索引没关系,select * 降低检索速度,是因为从数据库服务器端到客户端的网络传输是有时间的,select * 中难免包含着不必要的字段,所以传输起来会比较慢。

 

接下来单纯的比较一下select * select 单个字段在速度上的区别。如果数据量非常非常大的话,这种速度上的差别是非常明显的。下边这个例子,是从相同的数据库表中去拿数据。

 

当只是返回一个OUT_ID字段的时候,你可以看到49秒钟的时候就处理了30万条数据。





这时候我们使用select * 这种方式,我们发现,在用事一分钟的时候,才处理了3万条数据。




从上边的对比中我们可以看出,在数据量非常大而且数据表字段非常多的时候,这两种方式在检索时间上的差别还是非常大的。

 

 

http://blog.csdn.net/michaelenshi/article/details/8855643

http://blog.csdn.net/kennyrose/article/details/7532032

http://www.zhihu.com/question/37777220

 


猜你喜欢

转载自blog.csdn.net/sundacheng1989/article/details/53117172
今日推荐