日期:2014-05-16  浏览次数:20655 次

filleactor 和pad_index
如果 SQL Server 数据库要经历大量的插入活动,那么很重要的一点是进行计划,以便在索引页和数据页上提供和维持开放空间,防止出现页拆分。当某个索引页或数据页不再能容纳任何新的行,但由于该页中所定义的数据的逻辑顺序需要插入一行时,便会发生页拆分。发生页拆分时,SQL Server 需要分割整页中的数据,并将大约一半数据移动到新的页,以使这两页均有一些开放空间。这会消耗一些系统资源和时间。

当最初生成索引时,SQL Server 将索引 B 树结构放置在连续的物理页上,以便通过连续 I/O 扫描索引页获取最佳 I/O 性能。当由于发生页拆分,需要将新的页插入索引的逻辑 B 树结构时,SQL Server 必须分配新的 8 KB 索引页。这种插入发生在硬盘上的其它位置,从而打断了索引页的物理连续特性。它使 I/O 操作从连续变为不连续,从而使得性能减低一半。可以通过重建索引页以恢复索引页的物理连续顺序来解决过多的页拆分。聚集索引的叶级也会遇到相同的问题,从而影响表的数据页。

请在 Performance Monitor 中关注“SQL Server: Access Methods - Page Splits”。此计数器中的非零值表示发生了页拆分,应用 DBCC SHOWCONTIG 进一步分析。有关如何使用此命令的细节,请在 SQL Server Books Online 中搜索“DBCC SHOWCONTIG”。

DBCC SHOWCONTIG 是非常有用的命令,可用它来检查表中是否发生了过多的页拆分。Scan Density 是 DBCC SHOWCONTIG 所提供的关键指示器。这个值越接近 100% 越好。如果这个值低于 100%,使用 DROP_EXISTING 选项在该表上重建聚集索引以便对这个表进行整理。CREATE INDEX 语句的 DROP_EXISTING 选项允许重建已有的索引,提供比先除去索引然后重建索引更好的重建性能。有关详细信息,请在 SQL Server Books Online 中搜索字符串“Create Index”和“rebuilding an index”。

CREATE INDEX 和 DBCC REINDEX 命令中的 FILLFACTOR 选项提供一种方法,以指定在索引页和数据页中要留出的开放空间的百分比。CREATE INDEX 的 PAD_INDEX 选项在非叶级索引页中应用为 FILLFACTOR 所指定的百分比。如果没有 PAD_INDEX 选项,FILLFACTOR 将主要影响聚集索引的叶级索引页。将 PAD_INDEX 选项与 FILLFACTOR 一起使用是一个不错的主意。有关详细信息,请在 SQL Server Books Online 中搜索“page split”和“pad_index”。

为 FILLFACTOR 指定的最佳值取决于给定时间帧内插入一个 8 KB 索引页和数据页中的新数据量。要记住的重要一点是,SQL Server 索引页中所包含的行通常比数据页要多得多,因为索引页只包含与索引相关的列的数据,而数据页则包含整行数据。同时还需记住多久出现一次维护窗口,以重建索引避免产生页拆分。仅当大多数索引页和数据页已填满数据时才开始重建索引。要使得这种情况得以发生,需要为给定的表正确选择聚集索引。如果聚集索引均匀分布数据,以至新的行插入与该表相关的所有数据页中,数据页将均匀填充。总而言之,这将延缓页拆分的发生,并且它是重建聚集索引所必需的条件。需要确定的另一方面是 FILLFACTOR,其选择一部分根据预计将在给定时间帧内插入 8 KB 页的键范围内的行数,以及系统中预定的索引重建发生的频率。

在这种情况下也需要进行抉择,以便找到一种既在页中留出足够的开放空间又适当产生页拆分的性能折衷方案。如果为 FILLFACTOR 指定一个小的百分比,它将在索引页和数据页中留出大量的开放空间。这有助于避免产生页拆分,但是却无法通过将数据压缩到页中改善性能。索引页和数据页上的压缩数据越多,SQL Server 运行越快,因为如果数据页和索引页上的压缩数据越多,则通常情况下可以用更少的页和 I/O 操作提取更多的数据。将 FILLFACTOR 指定得过高会使页中留出的开放空间过少,使得页溢出的速度过快,从而引起页拆分。

在使用 FILLFACTOR 和 PAD_INDEX 之前,需记住读操作往往大大超过写操作,即便在联机事务处理 (OLTP) 系统中也是如此。使用 FILLFACTOR 将减慢所有的读操作,因为它使表更加分散(减少了数据压缩)。比较好的方法是在使用 FILLFACTOR 和 PAD_INDEX 之前,使用 Performance Monitor 将 SQL Server 的读操作和写操作进行比较,仅当写操作占了读操作的相当大一部分(也就是说超过 30%)的时候使用这些选项。

如果写操作占了读操作的相当大一部分,那么在十分繁忙的 OLTP 系统中,最佳的方法是尽可能地指定一个高的 FILLFACTOR,这将在每个 8 KB 页中留出最少量的可用空间,但仍然能防止发生页拆分,并可使 SQL Server 到达下一个可用时间窗口重建索引。这种方法既获得了 I/O 性能(尽可能地使页填满)又避免了页拆分(不让页溢出)。这可能需要进行一些实验,如用不同的 FILLFACTOR 值重建索引,然后模拟表中的负载活动以验证最佳的 FILLFACTOR 值。在确定了最佳的 FILLFACTOR 值后,可使预定的索引重建任务像 SQL Server Task 一样自动执行。有关使任务自动进行的详细信息,请在 SQL Server Books Online 中搜索字符串“creating a task”。[/size][size=xx-small]

如果 SQL Server 数据库中没有写活动,可以将 FILLFACTOR 设为 100%,以便完全填满所有的索引页和数据页,从而获得最佳的 I/O 性能。