索引-总结

来源:互联网 发布:windows原版aero主题 编辑:程序博客网 时间:2024/05/18 03:01


一、索引的概念
在关系数据库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种数据结构(存储结构+算法),它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容。
索引提供指向存储在表的指定列中的数据值的指针,然后根据您指定的排序顺序对这些指针排序。数据库使用索引以找到特定值,然后顺指针找到包含该值的行。这样可以使对应于表的SQL语句执行得更快,可快速访问数据库表中的特定信息。
当表中有大量记录时,若要对表进行查询,第一种搜索信息方式是全表搜索,是将所有记录一一取出,和查询条件进行一一对比,然后返回满足条件的记录,这样做会消耗大量数据库系统时间,并造成大量磁盘I/O操作;第二种就是在表中建立索引,然后在索引中找到符合查询条件的索引值,最后通过保存在索引中的ROWID(相当于页码)快速找到表中对应的记录。


索引是与表关联的可选结构。可以创建索引加快对表执行查询SQL语句的速度。就像书的索引可以帮助我们更快的查找信息一样,Oracle中的索引也提供了一种更快的访问数据的途径。


所以说白了,索引问题就是一个查找问题,
数据库索引,是数据库管理系统中一个排序的数据结构(存储结构+算法),以协助快速查询数据库表中数据。索引的实现通常使用B树及其变种B+树。
在存储数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引。
为表设置索引要付出代价的:一是增加了数据库的存储空间,二是在插入和修改数据时要花费较多的时间(因为索引也要随之变动)。

一个普通索引的b-树结构:




二、索引的优点、缺点
优点:创建索引可以大大提高系统的性能。
  1、通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
  2、可以大大加快数据的检索速度,这也是创建索引的最主要的原因。
  3、可以加速表和表之间的连接,特别是在实现数据的参照完整性方面特别有意义。 (参考 参照完整性章节)
  4、在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。 
  5、通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。  (参考 优化隐藏器章节)


缺点:增加索引也有许多不利的方面。
  1、创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。
  2、索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。
  3、当对表中的数据进行增加的时候,索引也要动态的维护,这样就降低了数据的维护速度。


三、索引 适合场景及不适合场景
索引是创建在数据库表的某些列上面的。在创建索引的时候,应该考虑那些列上可以创建索引,那些列上不应该创建索引。
符合创建索引的条件:
  1、在经常需要搜索的列上,可以加快搜索的速度。
  2、在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构。
  3、在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度。
  4、在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的,速度要快。
  5、在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询速度。
  6、在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。


有些列不应该创建索引:
  1、对于那些在查询中很少使用或者参考的列不应该创建索引。这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。
  2、对于那些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。
  3、对于那些定义为text、clob、image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。
  4、当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改性能远远大于检索性能时,不应该创建索引。或者说列修改频率远远大于列查询频率时,不应该创建索引。
PS:对于第4条,笔者需要多说一句,经过实际测试,更新少量数据的时候有索引会增加效率,所以这里的"修改性能"不单纯只update的意思,应该是一个概括,比如当删除、修改大量数据的时候这种情况就属于修改性能远远大于检索性能,但我们也应该认识到,实际开发过程中基本不太可能出现一次更新大量数据的情况。


四、索引的内容
索引的内容组成可以根据 聚集索引、非聚集索引来划分。以B树索引为例,它们的主要区别在于叶子节点,
聚集索引的内容,叶子节点就是数据节点,即包含索引指针和整列数据;当然每一个枝干节点和根节点都包含索引对应的列的数值;
非聚集索引的内容,叶子节点包括索引对应的列的数据和数据所对应的ROWID,当然每一个枝干节点和根节点都包含索引对应的列的数值。


五、个人总结
我们应该通过现象看本质,其实索引对数据库的影响,关键就在于I/O的次数以及I/O的数据量上,无论是查询、增加、删除、修改,如果能减少I/O次数 就会变快,如果增加了I/O次数就会变慢。
在一本书上看到这样一句话,原话是:“索引通常能提高查询的性能。select语句、update和delete命令的where子句的性能(当访问的行较少时)可以从索引中获益。” 
普通索引,实际测试,确实如此。

索引改进性能的程度取决于数据的选择性,以及在表的块之间分布数据的方式。如果数据非常具有选择性,则表中的将只有很少的行匹配索引值(例如身份证号码),oracle将能够快速查询匹配的索引值的ROWID的索引,并且可以快速查询少量的相关数据块。如果数据不是非常具有选择性(例如国家名),则索引值可能返回很多rowid,导致从表中查询许多单独的块。
如果数据非常具有选择性,但是相关的行在表中的存储位置并不互相靠近(非聚集索引),则会进一步减少索引的益处。如果匹配索引值的数据分散在表的多个块中,则必须从表中选择多个单独的块以满足查询。在一些情况中,当数据分散在表的多个块中时(其实就是查询大量数据时,比如大于表中总数据的5%),最好是不使用索引,而是执行权表扫描,执行权表扫描时,oracle使用多块读取以快速扫描表。基于索引的读取是单块读取,因此在使用索引时的目标是减少解决查询所需的单个块的数量。


看完这个我们就会冒出来很多问题,比如:
索引真的可以加快查询速度嘛?对添加、删除、更新有什么影响呢?
外键到底要不要加索引呢? 索引-外键参照完整性

索引有哪些种类,mysql、oracle 它们索引种类、用法都一样吗?


接下来再开一片新的文章: 索引-数据测试


原创粉丝点击