【数据库】数据库索引探索

一、索引是什么?


数据库的数据存储在磁盘中,当用户或者程序通过DBMS查询数据库某条记录时,就会将磁盘中对应的数据读取到内存中。但是问题是,假如所查询的表的数据量很大,而内存是有限的,在没有索引的情况下,查询将对整个表进行扫描,就需要多次IO读取磁盘中的数据,通过“遍历”数据块的方式找到需要的记录。这个性能消耗很大,并且会很慢。
索引就是用来解决这个问题。对一个字段添加索引,那么会维护这个字段的索引数据,当查找这个关键字段的数据,就会将索引数据加载到内存中去,通过索引数据找到这个关键字段,而在索引中每个关键字段会指向对应的记录,或者一个桶(桶中存储对应记录的指针)。具体数据结构可以通过B树、Hash表实现。

具体例子:
假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,可以存储100条记录。如果没有索引,查询将对整个表进行扫描,最坏情况下,所有数据页都不在内存中,需要读取log100(10^6)=10^4个页面,如果这些页面在磁盘上随机分布,需要进行10^4次I/0,假设磁盘每次I/O时间为10ms,则总共需要100s。如果对之简历B-Tree索引,则只需要进行log100(10^6)=3次页面读取,最坏情况下耗时30ms。

二、索引的实现


索引是在存储引擎中实现的。存储引擎是指内存存储、事务处理支持等不同的技术以及配套的相关功能。我的理解是,数据存储所用的数据结构的差异,使得支持不同的技术和功能,划分成不同的存储引擎。下面就来浅谈三种索引数据结构。

1.B+Tree索引

先来看一下B树的定义:

一棵m阶平衡树或者为空,或者满足以下条件:
① 每个结点至多有m棵子树
② 根结点为叶结点,或至少有两棵子树
③ 每个非叶结点至少有[m/2]棵子树
④ 从根结点到叶结点的每一条路径都有同样的长度,即叶结点在同一层次上

m阶平衡很好地适应了内存有限,DBMS分块读取数据这个特点。

看一下B+树

一棵m阶B+树是一棵平衡树,按下面方式组织
① 每个节点中至多有m-1个查找键值K1,K2,……,Km-1,m个指针P1,P2,……,Pm。
② 叶结点中的指针指向所查找的记录
两种情况:
a.查找键恰好是主文件的主键(非空、唯一),那么叶结点中的指针直接指向主文件中的记录。例如指针Pi指向查找键值为Ki的主记录。
b. 查找键不是主文件的主键,并且查找键值的顺序也不是主文件的顺序,那么叶结点中的指针指向一个桶,桶中存放指向具有该查找键值的主记录的指针。
③ 非叶结点的组织方式
对于指针P跟键值K有,Pi指向的子树中的所有查找键值均大于或等于Ki-1,而均小于Ki。

2.BTree索引

类似于B+树,区别在于,B树中的所有查找键值只出现一次。
在B+树中,每个查找键值都必须在叶结点中出现,为了组织多级索引,某些查找键值还必须在上层结点中出现。在B+树中,查找键值可以出现在任何节点上,但只能出现一次。
所以在B树中,查找键值如果出现在非叶结点,那么需要在它出现的地方附加上一个指向主记录的指针。

3.Hash索引

散列方法是指根据记录的查找键值,使用一个函数计算得到的函数值作为磁盘块的地址,对记录进行存储和访问。在数据库技术中,一般使用“桶”作为基本的存储单位,一个桶可以存放多条记录。

桶溢出解决方法
  • 溢出桶拉链法
    溢出的桶用指针链接在原来的桶的后面。
  • 开放式散列法
    • 线性探查法
      在溢出桶位置的下面顺序选择一个空闲的桶。
    • 再散列探查法
      如果桶溢出,则使用第二个散列方法再选择另外一个桶位置。

hash索引跟B树索引一个很大的区别是,hash索引只能进行确定值的搜索,而不能模糊搜索。因为hash索引搜索是通过得到关键值的hash方法值,来得到记录的地址,所以也不能通过hash索引进行排序。

三、索引的利弊

优点

  • 大大加快数据的检索速度 (最主要的原因)
  • 可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义
  • 在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间
  • 通过创建唯一索引,可以保证数据库表中每一行数据的唯一性

缺点

  • 创建索引和维护索引需要耗费时间,并且随着数据量的增加而增加
  • 索引需要占用物理空间
  • 当对表中的数据进行增加、删除和修改的时候,索引也需要动态维护,降低了数据的维护速度。

所以,是否创建索引需要根据具体需要,权衡索引的利弊来使用索引。

索引的适用情况

  • 经常需要搜索范围搜索(hash索引不支持范围搜索)的列,可以加快搜索的速度
  • 作为主键的列,强制该列的唯一性和组织表中数据的排列结构
  • 经常用在连接的列,这些列主要是一些外键,可以加快连接的速度
  • 经常需要排序的列

索引的不适用情况

  • 很少使用适用或者参考的列。因为很少使用到,查询速度并没有明显区别,相反由于增加索引而降低了系统的维护速度和增加了空间需求。
  • 只有很少数据值的列。列的取值很少,那么索引就起不了什么作用了,因为B树没有区分度,而hash则会大量重复。
  • 定义为test、image、bit数据类型的列不应该增加索引。这些数据量很大,或者取值很少。
参考资料

《数据库系统教程》 施伯乐等著 高等教育出版社
http://www.cnblogs.com/hustcat/archive/2009/10/28/1591648.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Oracle数据库是一种关系型数据库管理系统,它提供了强大的查询功能来检索和操作存储在数据库中的数据。下面是一些常用的Oracle数据库查询技巧和语法: 1. SELECT语句:用于从数据库中检索数据。可以使用SELECT语句选择特定的列、过滤条件、排序和聚合函数等。 2. WHERE子句:用于在SELECT语句中添加过滤条件,以限制返回的结果集。可以使用比较运算符(如等于、大于、小于等)、逻辑运算符(如AND、OR)和通配符(如LIKE)来构建条件。 3. ORDER BY子句:用于对查询结果进行排序。可以按照一个或多个列进行升序或降序排序。 4. GROUP BY子句:用于将查询结果按照一个或多个列进行分组,并对每个组应用聚合函数(如SUM、AVG、COUNT等)。 5. HAVING子句:用于在GROUP BY子句后添加过滤条件,以限制返回的分组结果。 6. JOIN操作:用于将多个表连接在一起,以便在查询中同检索相关的数据。常见的JOIN类型包括INNER JOIN、LEFT JOIN、RIGHT JOIN和FULL JOIN。 7. 子查询:可以在SELECT语句中嵌套一个或多个查询,以便在查询中使用子查询的结果。 8. 联合查询:使用UNION操作符可以将多个SELECT语句的结果合并为一个结果集。 9. 视图:可以创建一个虚拟的表,该表是基于一个或多个表的查询结果。视图可以简化复杂的查询,并提供更好的数据安全性。 10. 索引:可以在数据库表上创建索引,以提高查询性能。索引可以加快数据检索速度,但会增加数据插入、更新和删除的开销。 这些只是Oracle数据库查询的一些基本技巧和语法,还有很多其他高级的查询功能和特性可以进一步探索和学习。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值