数据结构-索引-理论

数据结构-索引-理论

理论部分摘录自百度百科和网络。

一、理论

(一)索引的定义

什么是索引?

1、索引

索引是为了加速对表中数据行的检索而创建的一种分散的存储结构。

索引已经成为关系数据库非常重要的部分。它们被用作包含所关心数据的表指针。

通过一个索引,能从表中直接找到一个特定的记录,而不必连续顺序扫描这个表,一次一个地去查找。

对于大的表,索引是必要的。没有索引,要想得到一个结果要等好几个小时、好几天,而不是几秒钟。

在关系数库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容。

索引提供指向存储在表的指定列中的数据值的指针,然后根据您指定的排序顺序对这些指针排序。数据库使用索引以找到特定值,然后顺指针找到包含该值的行。这样可以使对应于表的SQL语句执行得更快,可快速访问数据库表中的特定信息。

当表中有大量记录时,若要对表进行查询,第一种搜索信息方式是全表搜索,是将所有记录一一取出,和查询条件进行一一对比,然后返回满足条件的记录,这样做会消耗大量数据库系统时间,并造成大量磁盘I/O操作;第二种就是在表中建立索引,然后在索引中找到符合查询条件的索引值,最后通过保存在索引中的ROWID(相当于页码)快速找到表中对应的记录。

索引(在 MySQL 中也叫“键key”)是存储引擎快速找到记录的一种数据结构。——《高性能MySQL》

索引是表的目录,在查找内容之前可以先在目录中查找索引位置,以此快速定位查询数据。对于索引,会保存在额外的文件中。索引,是数据库中专门用于帮助用户快速查询数据的一种数据结构。

2、Oracle索引概念

在oracle中,索引是一种供服务器在表中快速查找一个行的数据库结构。在数据库中建立索引主要有以下作用。
  (1)快速存取数据。
  (2)既可以改善数据库性能,又可以保证列值的唯一性。
  (3)实现表与表之间的参照完整性
  (4)在使用orderby、groupby子句进行数据检索时,利用索引可以减少排序和分组的时间。

3、Mysql索引概念

MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。

打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车。

拿汉语字典的目录页(索引)打比方,我们可以按拼音、笔画、偏旁部首等排序的目录(索引)快速查找到需要的字。

索引分单列索引和组合索引。单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。组合索引,即一个索引包含多个列。

创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。

实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。

上面都在说使用索引的好处,但过多的使用索引将会造成滥用。因此索引也会有它的缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。

建立索引会占用磁盘空间的索引文件。

(二)索引的作用

在数据库系统中建立索引主要有以下作用:

(1)快速取数据;

(2)保证数据记录的唯一性;

(3)实现表与表之间的参照完整性;

(4)在使用ORDER by、group by子句进行数据检索时,利用索引可以减少排序和分组的时间。

(三)索引的优缺点

1、优点

(1)大大加快数据的检索速度;

(2)创建唯一性索引,保证数据库表中每一行数据的唯一性;

(3)加速表和表之间的连接;

(4)在使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间。

2、缺点

(1)索引需要占物理空间。

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

索引的缺点是创建和维护索引需要耗费时间

索引可以提高查询速度,会减慢写入速度

索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。

一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。

(四)索引的类型

1、索引分类

(1)普通索引

最基本的索引类型,没有唯一性之类的限制。

(2)唯一索引

唯一索引是不允许其中任何两行具有相同索引值的索引。

当现有数据中存在重复的键值时,大多数数据库不允许将新创建的唯一索引与表一起保存。数据库还可能防止添加将在表中创建重复键值的新数据。例如,如果在 employee 表中职员的姓 (lname) 上创建了唯一索引,则任何两个员工都不能同姓。

对某个列建立UNIQUE索引后,插入新记录时,数据库管理系统会自动检查新纪录在该列上是否取了重复值,在CREATE TABLE 命令中的UNIQE约束将隐式创建UNIQUE索引。

(3)主键索引

简称为主索引,数据库表中一列或列组合(字段)的值唯一标识表中的每一行。该列称为表的主键。

在数据库关系图中为表定义主键将自动创建主键索引,主键索引是唯一索引的特定类型。该索引要求主键中的每个值都唯一。当在查询中使用主键索引时,它还允许对数据的快速访问。

提示尽管唯一索引有助于定位信息,但为获得最佳性能结果,建议改用主键索引。

(4)聚集索引

也称为聚簇索引,在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引, 即如果存在聚集索引,就不能再指定CLUSTERED 关键字。

索引不是聚集索引,则表中行的物理顺序与键值的逻辑顺序不匹配。与非聚集索引相比,聚集索引通常提供更快的数据访问速度。聚集索引更适用于对很少对基表进行增删改操作的情况。

如果在表中创建了主键约束,SQL Server将自动为其产生唯一性约束。在创建主键约束时,指定了CLUSTERED关键字或干脆没有制定该关键字,SQL Sever将会自动为表生成唯一聚集索引。

(5)非聚集索引

也叫非簇索引,在非聚集索引中,数据库表中记录的物理顺序与索引顺序可以不相同。

一个表中只能有一个聚集索引,但表中的每一列都可以有自己的非聚集索引。

如果在表中创建了主键约束,SQL Server将自动为其产生唯一性约束。在创建主键约束时,如果制定CLUSTERED关键字,则将为表产生唯一聚集索引。

(6)候选索引

与主索引一样要求字段值的唯一性,并决定了处理记录的顺序。在数据库和自由表中,可以为每个表建立多个候选索引。

(7)HASH索引

HASH索引可能是访问数据库中数据的最快方法,但它也有自身的缺点。集群键上不同值的数目必须在创建HASH集群之前就要知道。需要在创建HASH集群的时候指定这个值。使用HASH索引必须要使用HASH集群。

2、MySQL索引分类

(1)主键索引:加速查询 + 列值唯一(不可以有null)+ 表中只有一个

(2)唯一索引:加速查询 + 列值唯一(可以有null)

(3)普通索引:仅加速查询

(4)组合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并

(5)全文索引:对文本的内容进行分词,进行搜索

3、Oracle索引分类

  (1)B*树索引的存储结构类似书的索引结构,有分支和叶两种类型的存储数据块,分支块相当于书的大目录,叶块相当于索引到的具体的书页。Oracle用B*树机制存储索引条目,以保证用最短路径访问键值。默认情况下大多使用B*树索引,该索引就是通常所见的唯一索引、逆序索引。
  (2)位图索引存储主要用于节省空间,减少oracle对数据块的访问。它采用位图偏移方式来与表的行ID号对应,采用位图索引一般是重复值太多的表字段。位图索引之所以在实际密集型OLTP(联机事物处理)中用的比较少,是因为OLTP会对表进行大量的删除、修改、新建操作。Oracle每次进行操作都会对要操作的数据块加锁。以防止多人操作容易产生的数据库锁等待甚至死锁现象。在OLAP(联机分析处理)中应用位图有优势,因为OLAP中大部分是对数据库的查询操作,而且一般采用数据仓库技术,所以大量数据采用位图索引节省空间比较明显。当创建表的命令中包含有唯一性关键字时,不能创建位图索引,创建全局分区索引时也不能用位图索引。
  • 索引按功能和索引对象分还有以下类型。
  (1)唯一索引意味着不会有两行记录相同的索引键值。唯一索引表中的记录没有RowID,不能再对其建立其他索引。在oracle10g中,要建立唯一索引,必须在表中设置主关键字,建立了唯一索引的表只按照该唯一索引结构排序。
  (2)非唯一索引不对索引列的值进行唯一性限制。
  (3)分区索引是指索引可以分散地存在于多个不同的表空间中,其优点是可以提高数据查询的效率。
  (4)未排序索引也称为正向索引。Oracle10g数据库中的行是按升序排序的,创建索引时不必指定对其排序而使用默认的顺序。
  (5)逆序索引也称反向索引。该索引同样保持列按顺序排列,但是颠倒已索引的每列的字节。
  (6)基于函数的索引是指索引中的一列或者多列是一个函数或者表达式,索引根据函数或表达式计算索引列的值。可以将基于函数的索引建立创建成位图索引。
  另外,按照索引所包含的列数可以把索引分为单列索引和复合索引。索引列只有一列的索引为单列索引,对多列同时索引称为复合索引。

(五)如何设计索引

1、索引设计的原则

(1)适合索引的列是出现在where子句中的列,或者连接子句中指定的列

(2)基数较小的类,索引效果较差,没有必要在此列建立索引

(3)使用短索引,如果对长字符串列进行索引,应该指定一个前缀长度,这样能够节省大量索引空间

(4)不要过度索引。索引需要额外的磁盘空间,并降低写操作的性能。在修改表内容的时候,索引会进行更新甚至重构,索引列越多,这个时间就会越长。所以只保持需要的索引有利于查询即可。

2、索引选取类型

(1)越小的数据类型通常更好:越小的数据类型通常在磁盘、内存和CPU缓存中都需要更少的空间,处理起来更快。

(2)简单的数据类型更好:整型数据比起字符,处理开销更小,因为字符串的比较更复杂。

(3)尽量避免NULL:应该指定列为NOT nuLL,在MySQL中, 含有空值的列很难进行查询优化,因为它们使得索引、索引的统计信息以及比较运算更加复杂

3、什么场景不适合创建索引

第一,对于那些在查询中很少使用或者参考的列不应该创建索引。这是因 为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。

第二,对于那 些只有很少数据值的列也不应该增加索引。因为本来结果集合就是相当于全表查询了,所以没有必要。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比 例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。

第三,对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。

第四,当修改性能远远大于检索性能时,不应该创建索 引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因 此,当修改性能远远大于检索性能时,不应该创建索引。

第五,不会出现在where条件中的字段不该建立索引。

4、什么样的字段适合创建索引

1、表的主键、外键必须有索引;外键是唯一的,而且经常会用来查询

2、数据量超过300的表应该有索引;

3、经常与其他表进行连接的表,在连接字段上应该建立索引;经常连接查询,需要有索引

4、经常出现在Where子句中的字段,加快判断速度,特别是大表的字段,应该建立索引,建立索引,一般用在select ……where f1 and f2 ,我们在f1或者f2上建立索引是没用的。只有两个使用联合索引才能有用

5、经常用到排序的列上,因为索引已经排序。

6、经常用在范围内搜索的列上创建索引,因为索引已经排序了,其指定的范围是连续的

(六)注意事项

并非所有的数据库都以相同的方式使用索引。作为通用规则,只有当经常查询索引列中的数据时,才需要在表上创建索引。索引占用磁盘空间,并且降低添加、删除和更新行的速度。如果应用程序非常频繁地更新数据或磁盘空间有限,则可能需要限制索引的数量。在表较大时再建立索引,表中的数据越多,索引的优越性越明显。

可以基于数据库表中的单列或多列创建索引。多列索引使您可以区分其中一列可能有相同值的行。

如果经常同时搜索两列或多列或按两列或多列排序时,索引也很有帮助。例如,如果经常在同一查询中为姓和名两列设置判据,那么在这两列上创建多列索引将很有意义。

确定索引的有效性:

检查查询的 WHERE 和 JOIN 子句。在任一子句中包括的每一列都是索引可以选择的对象。

对新索引进行试验以检查它对运行查询性能的影响。

考虑已在表上创建的索引数量。最好避免在单个表上有很多索引。

检查已在表上创建的索引的定义。最好避免包含共享列的重叠索引。

检查某列中唯一数据值的数量,并将该数量与表中的行数进行比较。比较的结果就是该列的可选择性,这有助于确定该列是否适合建立索引,如果适合,确定索引的类型。、

(七)索引的数据结构:B-Tree和B+Tree

1、B-Tree和B+Tree

MySQL索引背后的数据结构及算法原理

2、为什么要选择B-Tree和B+Tree作为索引的数据结构

是什么影响了数据库索引选型?

(八)索引的实现原理:MyISAM和InnoDB

索引实现原理

(九)索引优化

MySQL——索引优化实战

MySQL——优化ORDER BY语句

MySQL——优化嵌套查询和分页查询

二、差异比较

待补充。

(一)MySQL

(二)Oracle

三、查漏补缺

待补充。

四、总结

五、参考

《高性能MySQL》

《深入浅出MySQL》

索引

数据库索引

Oracle索引

随笔分类 - MySQL

mysql索引的新手入门详解

CodingLabs

各种Oracle索引类型介绍

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章