技术开发 频道

设计SQL Server集簇索引以提升性能(一)

  【IT168 技术文档】SQL Server的集簇索引是数据库整体架构的一个非常重要的方面。它们经常被忽视、误解,或者如果数据库很小,它们会被认为是不重要的。

  本文阐述了集簇索引对于整个系统性能以及数据库增大时维护的重要性。我将主要说明SQL Server集簇索引是如何存储在硬盘中的,为什么它们应该一直随着时间增加以及为什么静态的集簇索引是最好的。我同时也将探讨多对多表,为什么它们会被使用,以及集簇索引如何能够让这些表效率更高。

  最后,很重要的是我们会讨论新的SQL Server 2005分割表概念,并探讨分割表是如何影响集簇索引的。这将有助于你以后作为出正确的决定性。


  集簇索引默认是与匹配主键相匹配的,而主键是定义在SQL Server表上的。然而,你可以在任何字段上创建一个集簇索引,然后在另一个字段或多个字段上定义一个主键。这时,这个主键将会作为一个唯一的非集簇索引被创建。典型地,一个集簇索引会与主键相匹配,但这并不是必须的,所以要仔细考虑。对于各种可能出现的情况,我将讨论集簇索引本身,而不管你是否选择将它与主键相匹配。


  集簇索引实际上装载了SQL Server的数据记录行,所以你的集簇索引存储的地方就是你的数据存储的地方。集簇索引是按数据范围而组织的。比如,1到10之间的值存储为一个范围,而90到110是另一个范围。因为集簇索引是按范围存储的,如果你需要在一个范围中搜索一个审计日志,使用基于日期字段的集簇索引效率会更高,其中日期字段会用于返回日期范围。非集簇索引更适用于具体值的搜索,比如“等于DateValue的日期”,而不是范围搜索,比如“在date1和date2之间的日期”。


  集簇索引的不断增加值


  集簇索引必须是基于值不断增加的字段。在前面的例子中,我使用了审计日志的日期字段,审计日志的日期值是不断增加的,而且旧的日期将不会再插入到数据表中。这就是一个“不断增加”字段。另一个不断增加值的好例子就是标识字段,它也是从创建后就持续恒定增加的。


  为什么我在这里花这么多时间讨论集簇索引的不断增加值呢?这是因为集簇索引的最重要的属性就是它们是不断增加的并且本质上是静止的。不断增加之所以重要的原因与我之前提到的范围架构有关。如果值不是不断增加的,SQL Server就必须在现有记录的范围内分配位置,而不是直接将它们放到索引后面的新的范围中。

 
如果值不是不断增加的,那么当范围的值用完后再出现一个已经用索引范围的值时,SQL Server将做一个页拆分插入一个索引。在实现时,SQL Server会将已填满的页拆分成两个单独的页,这两个页此时会有更多的值空间,但这需要更多的资源去处理。你可以通过设置填充参数为70%来作好预备工作,这样就可以有30%的自由空间来为后来的值使用。

  这个方法的问题是你必须不断地“再索引”集簇索引使它能维持30%的自由空间。对集簇索引进行再索引会带来繁重的I/O负载,因为它必须移动它的实际数据,并且任何非集簇索引都必须重建,这会增加许多的维护时间。

  如果集簇索引是不断增加的,你将不需要重建集簇索引。你可以将集簇索引的填充因数设置为100%,这样随着时间的推移,你就只需要对于不集中的、非集簇索引进行再索引,这样就可以增加数据库在线时间。

  不断增加的值将只会在索引的尾部添加新值,并且只在需要的时候才创建新的索引范围。由于新的值都只会不断地添加到索引的尾部而且填充因数为100%,所以将不再会有逻辑碎片出现。填充因数越高,每一页所填充的记录行就越多。更高的填充因数使得查询时会需要更少的I/O、RAM和CPU资源。你查询集簇索引中越少的数据类型,JOIN/查询操作速度会更快。同时,因为每一个非集簇索引都要求包括集簇索引键,所以集簇索引键和非集簇索引也会更小。

  集簇索引的非常好的数据类型是非常狭窄的。对于数据类型大小,它通常是smallint、int、bigint或datetime。当datetime值用作集簇索引时,它们是唯一的字段并且通常是不断增加的日期值,这些值通常是作为范围数据查询的。通常,你应该避免组合(多字段)集簇索引,除了以下情况:多对多数据表和SQL Server 2005分割表,这种分割表有分割的字段,它包含了集簇索引而允许索引排列。

0
相关文章