数据库索引总结

一、为什么要创建索引呢(长处)?
这是由于,创建索引能够大大提高系统的性能。


第一,   通过创建唯一性索引,能够保证数据库表中每一行数据的唯一性。
第二。   能够大大加快数据的检索速度。这也是创建索引的最基本的原因。
第三。   能够加速表和表之间的连接。特别是在实现数据的參考完整性方面特别有意义。
第四,   在使用分组和排序子句进行数据检索时,相同能够显著降低查询中分组和排序的时间。
第五,   通过使用索引,能够在查询的过程中,使用优化隐藏器。提高系统的性能。



二、建立方向索引的不利因素(缺点)
或许会有人要问:添加索引有如此多的长处。为什么不正确表中的每个列创建一个索引呢?这样的想法固然有其合理性,然而也有其片面性。尽管,索引有很多长处,可是。为表中的每个列都添加索引。是很不明智的。这是由于。添加索引也有很多不利的一个方面。

第一。   创建索引和维护索引要耗费时间,这样的时间随着数据量的添加而添加。
第二。   索引须要占物理空间,除了数据表占数据空间之外,每个索引还要占一定的物理空间。假设要建立聚簇索引。那么须要的空间就会更大。


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

三、创建方向索引的准则
索引是建立在数据库表中的某些列的上面。因此,在创建索引的时候,应该细致考虑在哪些列上能够创建索引,在哪些列上不能创建索引。


一般来说,应该在这些列上创建索引。
第一。   在常常须要搜索的列上,能够加快搜索的速度。
第二,   在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构。
第三,   在经经常使用在连接的列上,这些列主要是一些外键。能够加快连接的速度。
第四,   在常常须要依据范围进行搜索的列上创建索引。由于索引已经排序,其指定的范围是连续的;
第五。   在常常须要排序的列上创建索引。由于索引已经排序,这样查询能够利用索引的排序,加快排序查询时间。
第六,   在常常使用在WHERE子句中的列上面创建索引,加快条件的推断速度。 

相同,对于有些列不应该创建索引。一般来说。不应该创建索引的的这些列具有下列特点:
第一,             对于那些在查询中非常少使用或者參考的列不应该创建索引。这是由于。既然这些列非常少使用到。因此有索引或者无索引,并不能提高查询速度。

相反,由于添加了索引,反而减少了系统的维护速度和增大了空间需求。


第二。             对于那些仅仅有非常少数据值的列也不应该添加索引。这是由于。由于这些列的取值非常少,比如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的非常大比例,即须要在表中搜索的数据行的比例非常大。

添加索引,并不能明显加快检索速度。


第三,             对于那些定义为text, imagebit数据类型的列不应该添加索引。这是由于,这些列的数据量要么相当大,要么取值非常少。
第四,             当改动性能远远大于检索性能时,不应该创建索引。

这是由于,改动性能和检索性能是互相矛盾的。当添加索引时,会提高检索性能。可是会减少改动性能。当减少索引时,会提高改动性能。减少检索性能。

因此,当改动性能远远大于检索性能时。不应该创建索引。 
四、创建索引的方法 
创建索引有多种方法,这些方法包含直接创建索引的方法和间接创建索引的方法。


第一,   直接创建索引。比如使用CREATE INDEX语句或者使用创建索引向导。
第二。   间接创建索引。比如在表中定义主键约束或者唯一性键约束时。同一时候也创建了索引。


尽管。这两种方法都能够创建索引,可是,它们创建索引的详细内容是有差别的。 
使用CREATE INDEX语句或者使用创建索引向导来创建索引,这是最主要的索引创建方式。而且这样的方法最具有柔性。能够定制创建出符合自己须要的索引。在使用这样的方式创建索引时,能够使用很多选项,比如指定数据页的充满度、进行排序、整理统计信息等,这样能够优化索引。

使用这样的方法,能够指定索引的类型、唯一性和复合性,也就是说。既能够创建聚簇索引。也能够创建非聚簇索引,既能够在一个列上创建索引,也能够在两个或者两个以上的列上创建索引。 
通过定义主键约束或者唯一性键约束。也能够间接创建索引。主键约束是一种保持数据完整性的逻辑,它限制表中的记录有相同的主键记录。在创建主键约束时,系统自己主动创建了一个唯一性的聚簇索引。

尽管,在逻辑上,主键约束是一种重要的结构,可是,在物理结构上,与主键约束相相应的结构是唯一性的聚簇索引。换句话说,在物理实现上,不存在主键约束,而仅仅存在唯一性的聚簇索引。相同。在创建唯一性键约束时。也同一时候创建了索引,这样的索引则是唯一性的非聚簇索引。

因此,当使用约束创建索引时。索引的类型和特征基本上都已经确定了,由用户定制的余地比較小。 
当在表上定义主键或者唯一性键约束时。假设表中已经有了使用CREATE INDEX语句创建的标准索引时,那么主键约束或者唯一性键约束创建的索引覆盖曾经创建的标准索引。

也就是说,主键约束或者唯一性键约束创建的索引的优先级高于使用CREATE INDEX语句创建的索引。 
五、索引的特征 
    索引有两个特征,即唯一性索引和复合索引。 
唯一性索引保证在索引列中的所有数据是唯一的,不会包括冗余数据。

假设表中已经有一个主键约束或者唯一性键约束,那么当创建表或者改动表时,SQL Server自己主动创建一个唯一性索引。然而,假设必须保证唯一性,那么应该创建主键约束或者唯一性键约束。而不是创建一个唯一性索引。

当创建唯一性索引时。应该认真考虑这些规则:当在表中创建主键约束或者唯一性键约束时,SQL Server自己主动创建一个唯一性索引;假设表中已经包括有数据。那么当创建索引时,SQL Server检查表中已有数据的冗余性;每当使用插入语句插入数据或者使用改动语句改动数据时,SQL Server检查数据的冗余性:假设有冗余值,那么SQL Server取消该语句的运行,而且返回一个错误消息。确保表中的每一行数据都有一个唯一值,这样能够确保每个实体都能够唯一确认;仅仅能在能够保证实体完整性的列上创建唯一性索引,比如,不能在人事表中的姓名列上创建唯一性索引,由于人们能够有同样的姓名。 
复合索引就是一个索引创建在两个列或者多个列上。在搜索时,当两个或者多个列作为一个关键值时,最好在这些列上创建复合索引。当创建复合索引时,应该考虑这些规则:最多能够把16个列合并成一个单独的复合索引。构成复合索引的列的总长度不能超过900字节,也就是说复合列的长度不能太长。在复合索引中,全部的列必须来自同一个表中。不能跨表建立复合列;在复合索引中,列的排列顺序是很重要的,因此要认真排列列的顺序,原则上,应该首先定义最唯一的列,比如在(COL1COL2)上的索引与在(COL2COL1)上的索引是不同样的,由于两个索引的列的顺序不同;为了使查询优化器使用复合索引,查询语句中的WHERE子句必须參考复合索引中第一个列。当表中有多个关键列时。复合索引是很实用的。使用复合索引能够提高查询性能,降低在一个表中所创建的索引数量。 
六、索引的类型 
依据索引的顺序与数据表的物理顺序是否同样,能够把索引分成两种类型。一种是数据表的物理顺序与索引顺序同样的聚簇索引。还有一种是数据表的物理顺序与索引顺序不同样的非聚簇索引。

 
七、聚簇索引的体系结构 
索引的结构类似于树状结构。树的顶部称为叶级。树的其他部分称为非叶级,树的根部在非叶级中。

相同。在聚簇索引中,聚簇索引的叶级和非叶级构成了一个树状结构,索引的最低级是叶级。在聚簇索引中,表中的数据所在的数据页是叶级,在叶级之上的索引页是非叶级,索引数据所在的索引页是非叶级。在聚簇索引中,数据值的顺序总是依照升序排列。 
应该在表中经常搜索的列或者依照顺序訪问的列上创建聚簇索引。当创建聚簇索引时,应该考虑这些因素:每个表仅仅能有一个聚簇索引,由于表中数据的物理顺序仅仅能有一个;表中行的物理顺序和索引中行的物理顺序是同样的。在创建不论什么非聚簇索引之前创建聚簇索引,这是由于聚簇索引改变了表中行的物理顺序。数据行依照一定的顺序排列,而且自己主动维护这个顺序。关键值的唯一性要么使用UNIQUEkeyword明白维护。要么由一个内部的唯一标识符明白维护,这些唯一性标识符是系统自己使用的,用户不能訪问;聚簇索引的平均大小大约是数据表的百分之五,可是。实际的聚簇索引的大小经常依据索引列的大小变化而变化。在索引的创建过程中。SQL Server暂时使用当前数据库的磁盘空间。当创建聚簇索引时。须要1.2倍的表空间的大小,因此,一定要保证有足够的空间来创建聚簇索引。 
当系统訪问表中的数据时,首先确定在对应的列上是否存在有索引和该索引是否对要检索的数据有意义。假设索引存在而且该索引很有意义,那么系统使用该索引訪问表中的记录。系统从索引開始浏览到数据,索引浏览则从树状索引的根部開始。

从根部開始,搜索值与每个关键值相比較。确定搜索值是否大于或者等于关键值。

这一步反复进行。直到碰上一个比搜索值大的关键值,或者该搜索值大于或者等于索引页上全部的关键值为止。 
八、非聚簇索引的体系结构 
非聚簇索引的结构也是树状结构。与聚簇索引的结构很类似,可是也有明显的不同。

 
在非聚簇索引中,叶级仅包括关键值,而没有包括数据行。

非聚簇索引表示行的逻辑顺序。    非聚簇索引有两种体系结构:一种体系结构是在没有聚簇索引的表上创建非聚簇索引,还有一种体系结构是在有聚簇索引的表上创建非聚簇索引。 
假设一个数据表中没有聚簇索引,那么这个数据表也称为数据堆。当非聚簇索引在数据堆的顶部创建时,系统使用索引页中的行标识符指向数据页中的记录。行标识符存储了数据所在位置的信息。数据堆是通过使用索引分配图(IAM)页来维护的。IAM页包括了数据堆所在簇的存储信息。在系统表sysindexes中,有一个指针指向了与数据堆相关的第一个IAM页。

系统使用IAM页在数据堆中浏览和寻找能够插入新的记录行的空间。这些数据页和在这些数据页中的记录没有不论什么的顺序而且也没有链接在一起。

在这些数据页之间的唯一的连接是IAM中记录的顺序。当在数据堆上创建了非聚簇索引时,叶级中包括了指向数据页的行标识符。行标识符指定记录行的逻辑顺序。由文件ID、页号和行ID组成。这些行的标识符维持唯一性。非聚簇索引的叶级页的顺序不同于表中数据的物理顺序。这些关键值在叶级中以升序维持。 
当非聚簇索引创建在有聚簇索引的表上的时候,系统使用索引页中的指向聚簇索引的聚簇键。聚簇键存储了数据的位置信息。假设某一个表有聚簇索引,那么非聚簇索引的叶级包括了映射到聚簇键的聚簇键值,而不是映射到物理的行标识符。当系统訪问有非聚簇索引的表中数据时。而且这样的非聚簇索引创建在聚簇索引上。那么它首先从非聚簇索引来找到指向聚簇索引的指针。然后通过使用聚簇索引来找到数据。 
    当须要以多种方式检索数据时,非聚簇索引是很实用的。当创建非聚簇索引时,要考虑这些情况:在缺省情况下,所创建的索引是非聚簇索引。在每个表上面。能够创建不多于249个非聚簇索引。而聚簇索引最多仅仅能有一个。
系统怎样訪问表中的数据 
一般地,系统訪问数据库中的数据,能够使用两种方法:表扫描和索引查找。第一种方法是表扫描。就是指系统将指针放置在该表的表头数据所在的数据页上。然后依照数据页的排列顺序,一页一页地从前向后扫描该表数据所占有的所有数据页,直至扫描完表中的所有记录。在扫描时。假设找到符合查询条件的记录。那么就将这条记录挑选出来。最后。将所有挑选出来符合查询语句条件的记录显示出来。另外一种方法是使用索引查找。索引是一种树状结构,当中存储了keyword和指向包括keyword所在记录的数据页的指针。

当使用索引查找时,系统沿着索引的树状结构。依据索引中keyword和指针,找到符合查询条件的的记录。

最后。将所有查找到的符合查询语句条件的记录显示出来。

 
    SQL Server中。当訪问数据库中的数据时,由SQL Server确定该表中是否有索引存在。假设没有索引,那么SQL Server使用表扫描的方法訪问数据库中的数据。查询处理器依据分布的统计信息生成该查询语句的优化运行规划,以提高訪问数据的效率为目标,确定是使用表扫描还是使用索引。

 
九、索引的选项 
    在创建索引时。能够指定一些选项,通过使用这些选项,能够优化索引的性能。这些选项包含FILLFACTOR选项、PAD_INDEX选项和SORTED_DATA_REORG选项。

 
使用FILLFACTOR选项,能够优化插入语句和改动语句的性能。当某个索引页变满时,SQL Server必须花费时间分解该页。以便为新的记录行腾出空间。

使用FILLFACTOR选项,就是在叶级索引页上分配一定百分比的自由空间。以便降低页的分解时间。

当在有数据的表中创建索引时。能够使用FILLFACTOR选项指定每个叶级索引节点的填充的百分比。缺省值是0,该数值等价于100。在创建索引的时候,内部索引节点总是留有了一定的空间,这个空间足够容纳一个或者两个表中的记录。

在没有数据的表中。当创建索引的时候,不要使用该选项,由于这时该选项是没有实际意义的。另外,该选项的数值在创建时指定以后,不能动态地得到维护。因此,仅仅应该在有数据的表中创建索引时才使用。 
PAD_INDEX选项将FILLFACTOR选项的数值相同也用于内部的索引节点。使内部的索引节点的填充度与叶级索引的节点中的填充度相同。假设没有指定FILLFACTOR选项,那么单独指定PAD_INDEX选项是没有实际意义的。这是由于PAD_INDEX选项的取值是由FILLFACTOR选项的取值确定的。 
当创建聚簇索引时,SORTED_DATA_REORG选项清除排序,因此能够降低建立聚簇索引所须要的时间。

当在一个已经变成碎块的表上创建或者重建聚簇索引时,使用SORTED_DATA_REORG选项能够压缩数据页。当又一次须要在索引上应用填充度时,也使用该选项。当使用SORTED_DATA_REORG选项时,应该考虑这些因素:SQL Server确认每个关键值是否比前一个关键值高,假设都不高,那么不能创建索引;SQL Server要求1.2倍的表空间来物理地又一次组织数据;使用SORTED_DATA_REORG选项,通过清除排序进程而加快索引创建进程;从表中物理地拷贝数据。当某一个行被删除时,其所占的空间能够又一次利用;创建所有非聚簇索引;假设希望把叶级页填充到一定的百分比。能够同一时候使用FILLFACTOR选项和SORTED_DATA_REORG选项。 
十、索引的维护 
为了维护系统性能。索引在创建之后,因为频繁地对数据进行添加、删除、改动等操作使得索引页发生碎块,因此,必须对索引进行维护。

 
使用DBCC SHOWCONTIG语句,能够显示表的数据和索引的碎块信息。当运行DBCC SHOWCONTIG语句时,SQL Server浏览叶级上的整个索引页,来确定表或者指定的索引是否严重碎块。DBCC SHOWCONTIG语句还能确定数据页和索引页是否已经满了。

当对表进行大量的改动或者添加大量的数据之后,或者表的查询很慢时,应该在这些表上运行DBCC SHOWCONTIG语句。

当运行DBCC SHOWCONTIG语句时,应该考虑这些因素:当运行DBCC SHOWCONTIG语句时,SQL Server要求指定表的ID号或者索引的ID号。表的ID号或者索引的ID号能够从系统表sysindexes中得到;应该确定多长时间使用一次DBCC SHOWCONTIG语句。这个时间长度要依据表的活动情况来定。每天、每周或者每月都能够。 
使用DBCC DBREINDEX语句重建表的一个或者多个索引。当希望重建索引和当表上有主键约束或者唯一性键约束时,运行DBCC DBREINDEX语句。

除此之外。运行DBCC DBREINDEX语句还能够又一次组织叶级索引页的存储空间、删除碎块和又一次计算索引统计。当使用运行DBCC DBREINDEX语句时。应该考虑这些因素:依据指定的填充度。系统又一次填充每个叶级页。使用DBCC DBREINDEX语句重建主键约束或者唯一性键约束的索引;使用SORTED_DATA_REORG选项能够更快地创建聚簇索引。假设没有排列关键值,那么不能使用DBCC DBREINDEX语句;DBCC DBREINDEX语句不支持系统表。另外,还能够使用数据库维护规划向导自己主动地进行重建索引的进程。 
统计信息是存储在SQL Server中的列数据的样本。这些数据一般地用于索引列。可是还能够为非索引列创建统计。SQL Server维护某一个索引关键值的分布统计信息。而且使用这些统计信息来确定在查询进程中哪一个索引是实用的。

查询的优化依赖于这些统计信息的分布精确度。查询优化器使用这些数据样本来决定是使用表扫描还是使用索引。当表中数据发生变化时。SQL Server周期性地自己主动改动统计信息。索引统计被自己主动地改动,索引中的关键值显著变化。

统计信息改动的频率由索引中的数据量和数据改变量确定。

比如,假设表中有10000行数据,1000行数据改动了,那么统计信息可能须要改动。然而。假设仅仅有50行记录改动了,那么仍然保持当前的统计信息。除了系统自己主动改动之外,用户还能够通过运行UPDATE STATISTICS语句或者sp_updatestats系统存储过程来手工改动统计信息。

使用UPDATE STATISTICS语句既能够改动表中的所有索引,也能够改动指定的索引。 
使用SHOWPLANSTATISTICS IO语句能够分析索引和查询性能。使用这些语句能够更好地调整查询和索引。SHOWPLAN语句显示在连接表中使用的查询优化器的每一步以及表明使用哪一个索引訪问数据。使用SHOWPLAN语句能够查看指定查询的查询规划。当使用SHOWPLAN语句时,应该考虑这些因素。SET SHOWPLAN_ALL语句返回的输出结果比SET SHOWPLAN_TEXT语句返回的输出结果具体。然而。应用程序必须能够处理SET SHOWPLAN_ALL语句返回的输出结果。

SHOWPLAN语句生成的信息仅仅能针对一个会话。假设又一次连接SQL Server,那么必须又一次运行SHOWPLAN语句。

STATISTICS IO语句表明输入输出的数量,这些输入输出用来返回结果集和显示指定查询的逻辑的和物理的I/O的信息。

能够使用这些信息来确定是否应该重写查询语句或者又一次设计索引。

使用STATISTICS IO语句能够查看用来处理指定查询的I/O信息。

 
就象SHOWPLAN语句一样。优化器隐藏也用来调整查询性能。

优化器隐藏能够对查询性能提供较小的改进,而且假设索引策略发生了改变,那么这样的优化器隐藏就毫无用处了。因此。限制使用优化器隐藏,这是由于优化器隐藏更有效率和更有柔性。当使用优化器隐藏时,考虑这些规则:指定索引名称、当index_id0时为使用表扫描、当index_id1时为使用聚簇索引;优化器隐藏覆盖查询优化器,假设数据或者环境发生了变化。那么必须改动优化器隐藏。 
十一、索引调整向导 
索引调整向导是一种工具,能够分析一系列数据库的查询语句。提供使用一系列数据库索引的建议。优化整个查询语句的性能。对于查询语句,须要指定下列内容: 
查询语句,这是将要优化的工作量  
包括了这些表的数据库。在这些表中,能够创建索引,提高查询性能。
在分析中使用的表  
在分析中。考虑的约束条件。比如索引能够使用的最大磁盘空间  
这里指的工作量。能够来自两个方面:使用SQL Server捕捉的轨迹和包括了SQL语句的文件。

索引调整向导总是基于一个已经定义好的工作量。假设一个工作量不能反映正常的操作,那么它建议使用的索引不是实际的工作量上性能最好的索引。索引调整向导调用查询分析器,使用全部可能的组合评定在这个工作量中每个查询语句的性能。

然后,建议在整个工作量上能够提高整个查询语句的性能的索引。假设没有供索引调整向导来分析的工作量。那么能够使用图解器马上创建它。

一旦决定跟踪一条正常数据库活动的描写叙述样本。向导能够分析这样的工作量和推荐能够提高数据库工作性能的索引配置。

 
索引调整向导对工作量进行分析之后,能够查看到一系列的报告。还能够使该向导马上创建所建议的最佳索引,或者使这项工作成为一种能够调度的作业,或者生成一个包括创建这些索引的SQL语句的文件。 
索引调整向导同意为SQL Server数据库选择和创建一种理想的索引组合和统计,而不要求对数据库结构、工作量或者SQL Server

原文地址:https://www.cnblogs.com/cynchanpin/p/6878054.html