设置填充因子是否重要?我认为是。很多资料都提到,缺省的填充因子取值一般情况下是较优的,而且建议除非你很清楚在做什么,否则不要更改填充因子取值。就像数据库管理员常识那样,除非你理解你正在做什么,否则不更改任何设置是明智的。说得虽然没错,但是到底该如何确定填充因子取值,以及知道该做什么?我试图找到一个确定取值的简单公式。你猜结果如何?我找不到。

为了理解填充因子,有必要好好理解聚集和非聚集索引,堆表(heap tables),扩展盘区(extents),页(pages),页拆分(page splits),以及DBCC SHOWCONTIG命令结果。如果你不熟悉这些概念,我建议参考SQL Server联机帮助,或者相关背景的资料。理解SQL Server物理文件结构的组成是十分重要的。

基本上填充因子是指当索引被创建和重建时,指定存储记录的叶节点页空间的百分比。我们也许以前都看过这个定义,但是该定义中有一个常被人忽视的关键点--“当索引被创建和重建时”。一旦页拆分发生,经过拆分后生成的两个新页上,原来设置的填充因子取值就失效了。当索引创建时,如果指定填充因子为80,意味着每个页只使用80%的空间。在某个页填入数据后,例如添加新记录或者修改记录,页拆分为两个新页,并且填充空间均为50%。原来那个填充因子对这两个新页失效。如果你没有重建索引,那么除非数据量很小,或者数据更新很小,否则很可能会产生很多页拆分,并且最早的填充因子会失效。

还是那个问题,我们该设置填充因子为多少呢?取值低,则需要更多的页来存储数据,因而读取范围大;这会影响性能。取值高,则会造成大量的页拆分;同样会影响性能。页拆分同时消耗CPU和I/O资源,但页拆分本身确实是必要的。也许你知道在只读表上应该设置填充因子高,而有大量更新的表上应该设置较低。这个结论没错,但是关键是你怎么知道表上面数据的更新程度?正如我现在的数据库,要指出哪些表是更新较低的,而那些是较高的,是一件很花时间的任务。其中的一个数据库有22,000张表,所以你能想象,要做完上述的工作有多漫长了。并且即使同一张表上的不同索引也具有不同的碎片率。所以要定义“高”和“低”的设置,是一件令人绝望的事情。

我想在这里阐述的东西不是严格的科学,也不是放置四海皆准的方法,而是一般情况下,我经常遵循的常识性的东西,就象当创建物理模型时,经常在外键上创建索引的常规做法一样道理。因此我想我已经讲明白本文的性质了。请在一两个表上试用这些方法,看看到底效果如何。

目标

在索引大小和页拆分之间找到平衡点。当添加影响索引的数据时,较小的填充因子减少页拆分;较大的填充因子正好相反。

尽量减少扩展盘区交换次数,并保持页数据的连续。每个索引的扫描密度(Scan Density)指标越大越好。我就比较喜欢将扫描密度保持在90%或者更高的水平,虽然在索引重建时,并不总是能达到。

防止在索引重建后,每秒页拆分(page splits/sec)指标突然升高。这会导致我的服务器崩溃。

尽量使得每个索引的平均页密度(Average Page Density)指标越高越好。该指标越高,说明读取操作越少。

平均页密度(Average Page Density)接近或者高于填充因子取值。在完美的情况下,当索引重建时,Average Page Density取值应该在填充因子取值到100%之间。

保持数据库平稳持续增长。你可以监控索引重建前和重建后数据库磁盘容量的大小变化。如果重建后,占用空间减少了,是好现象。

在索引重建时,尽量保持性能参数平稳。如果只能有一个目标,我认为这就是我要选择的目标。上面的所有目标最终是为该目标服务的。我喜欢在整个过程中性能保持平稳和一致。如此,可以减少很多性能问题的担忧。

要紧的事先做,让我们开始吧

首先定义一个重建索引的调度作业。我会根据数据库的不同创建不同的调度。例如对于相对较小的数据库,我创建的调度作业为:在非高峰时间,对所有用户表执行DBCC DBREINDEX。在某些阶段,有些数据库会受到额外的关注。这对于如何设置填充因子是很重要的一个因素。填充因子的设置依赖于索引重建的频率。

下面将讲述一些调试数据库的规律性东西。你可以列举很多这样的规律,不过我想分享一些我认为更关键的规律。首先,性能监控时请关注Page Splits/Sec这个指标。记住页拆分是一项不得不做的工作,同时也因此而带来性能问题。其次,获取DBCC SHOWCONTIG的信息。我有一个调度作业,该作业每个星期执行一次DBCC SHOWCONTIG,负责获取我所有服务器上的用户数据库结果,并放到某个表中。当然我会在这些信息上添加实例和数据库名字的字段以方便查询分析。运行DBCC SHOWCONTIG,并加上ALL_INDEXES和TABLERESULTS的选项。TABLERESULTS选项能让我们方便地读取和操作结果数据。ALL_INDEXES选项是必要的,因为如果没有该选项,你看的的结果是针对聚集索引和堆的。我们需要掌握全局并分别对待每个索引。这是因为某个表上的某个索引的好坏,并不意味该表上别的索引也有相同结论。一个索引也许建立在相对变化大的字段上,而另一个也许建立在相对静态的字段上。因此你还应该获取一系列的表名,索引,以及sysindexes表中的OrigFillFactor数值

Ok,让我们按照这些准则并将其应用在数据库上。由于DBCC SHOWCONTIG需要消耗资源,所以最好在系统不那么繁忙的时间做该工作。也许你的数据库有许多表和索引,所以最好能够按字母顺序或者按行数来排列得到的结果。起初,看那些结果会比较麻烦,不过只要用一段时间,你就会慢慢体会到那些数值的重要性了。

在每次调度中执行DBREINDEX命令。总是要留意的是,该命令的执行会十分消耗资源,在某些情况下有可能让数据库崩溃,而且我直觉地认为会降低数据库性能。比如当填充因子设置为100,并且数据库同时有大量的insert操作的时候。此时会发生什么?首先,数据库会有大量的页拆分。因为填充因子取值设置不当,重建索引工资也许会在好几天内都对性能产生影响。

在重建索引后,监视Page Splits/Sec指标,看看是否上升了。从重建索引开始,直到下一次重建前,之间间隔要超过24小时。在这段时间内需要获取三次Page Splits/Sec的取值,一次是在索引重建完成时,一次是距离下次重建的中间时间点,还有一次就是下次重建前一刻。

在下次重建前的24小时内,运行DBCC SHOWCONTIG,并保存结果信息。

利用最初的填充因子取值,和由DBCC SHOWCONTIG命令获得的信息,就可以开始进行新的填充因子设置了。通过重建索引的调度作业,在上述时间段内观察索引的碎片程度,当然,前提是事务造成的容量变化不大。

我并不会纠缠较小的索引。所谓较小的索引,不仅指索引对应的记录数小,而且指涉及的页数小。这样可以减少很多分析的时间,而且填充因子的修改也不至于影响太大。关于每个索引,可以通过Scan Density指标来观测。通常,这个指标是关键,不过也有例外。如果Page Density指标为24%,这就意味着索引正被拆分了,一些数据发生改变了。当平均Page Density为50%,而原始的填充因子取值为90,那么可能有问题了。既然我知道下次索引会在什么时候被重建,所以我还会看看,当原始的填充因子为80,并且平均Page Denisty为我要增加的填充因子取值的90%时的情形。

填充因子设置的一般性准则和指导

索引重建任务的时间间隔要相对一致。

如果索引较小,就没有必要去调整填充因子。

在索引级别上进行监控和更新,而不是表级别上。

保存填充一直在0,或者75和100之间。如果你要将填充因子设置为低于75,那么你必须自信你在做什么。保持较低的Scan Density和较低的平均Page Density是十分重要的情形。做一些观察,在将填充因子取值降低前,找出表被读取的频繁程度。

如果Scan Density高于或等于90%,别去改变填充因子,或者调整任务中填充因子至少不应该是首先被调整的。

如果Scan Density在60%到90%之间,小小地降低一下填充因子,例如降低幅度2%。

如果Scan Density低于60%,则加大降低填充因子的幅度。填充因子的取值我一般会取平均Page Density和最初的填充因子之间的中值。例如Original Fill factor = 100,Average Page Density = 60,那么我就取填充因子为80。

如果Average Page Density大于Original Fill Factor,并且Scan Density接近于100%,那么要提高填充因子取值。这样做很好,因为你可以把更多的数据放在同一个页中。例如:Fill Factor = 80,Scan Density = 98,Average Page Density = 88。此时,在下次索引重建之前,页面按照8%的速度填充,而且该速度相对持续稳定;这种情况吓,就可以提高填充因子取值,但是不要超过92。因为按照8%的增长速度,页面马上会填充到100%而引起页拆分。我建议是提高到88%,并且开始观察下一步数据变化如何。

要力图避免改变填充因子过快。我建议多观察一些周期,然后微调。

这就是我提供的设置填充因子的常规原则和步骤。如果你索引重建周期很规律,你就可以发现索引碎片如何。通过使用DBCC SHOWCONTIG获取的数据,可以在下次索引重建前,辅助你来决定填充因子的新取值。通过监视指标,可以慢慢学到页拆分和填充因子设置的技巧。我曾经尝试得出设置填充因子的公式,这花了我很多时间。上面列举的规则很直观,一般情况下我会将填充因子尽可能的设置高一些。在很多情况下,这是基本的准则。

看完上面的规则后,你会觉得这并不难。因此快点应用到实际上,但是不要期望结果是十全十美的,因为这和目标有关。

其它的观点和考虑

使用时间长的数据库的填充因子一般来说比新数据库要高。这很容易解释。很多表增长是一个常数,既不是线性也不是指数型。假设某个索引最初需要1000页,索引重建期间扩展了500页,填充因子值位90。这相当于空余0.10*8096=790KB的容量用于后面数据的增加或更新。此时的填充因子被认为也许高了一些,应该调低。但是一旦填充因子同样为90,但是如果那个表最初有10,000页,那么意味着有大约7906KB的空闲空间可以用于后面的数据增加或更新。因此10,000页的时候,提高填充因子取值是有利的。当设置填充因子的时候,索引的增长和大小是必须考虑的。

和较小的表/索引相比,具有低扫描密度或者大幅度下降的平均页密度的大表/索引更应该被关注。它们具有更多的页拆分,这些页拆分会给较大的索引带来大幅度的下降。因为我们的目标是减少页拆分!一个十分大的索引下降2%的扫描密度,从纯量上看,远远大于较小的索引降低30%的的幅度。

密切关注通过SHOWCONTIG得到的扫描密度和平均页密度指标。从这两个指标,可以得到很多相关的信息。

sysindexes表中的初始填充因子取值并不代表索引创建时的填充因子取值,至少该取值并非是必要的。该数值只在最后一次创建或重建时有用。

你可以用同样的方法来考查堆表的情况。

当你觉得填充因子设置合适后,请在一段时间后再观察一下。这需要不断的维护。

编辑推荐:

mysql索引填充因子_处理索引碎片,填充因子(FILLFACTOR)相关推荐

  1. hive能加快MySQL查询速度吗_建立索引可以加快表中数据查询的速度吗

    首先明白为什么索引会增加速度,DB在执行一条Sql语句的时候,默认的方式是根据搜索条件进行全表扫描,遇到匹配条件的就加入搜索结果集合. 如果我们对某一字段增加索引,查询时就会先去索引列表中一次定位到特 ...

  2. mysql 索引 数据页_数据库索引数据页

    索引的好处 索引带来的益处可能很多读者会认为只是"能够提高数据检索的效率,降低数据库的IO成本". 确实,在数据库中表的某个字段创建索引,所带来的最大益处就是将该字段作为检索条件时 ...

  3. mysql联合索引怎么存储_联合索引在B+树上的存储结构及数据查找方式

    能坚持别人不能坚持的,才能拥有别人未曾拥有的. 关注编程大道公众号,让我们一同坚持心中所想,一起成长!! 引言 上一篇文章<MySQL索引那些事>主要讲了MySQL索引的底层原理,且对比了 ...

  4. mysql聚集索引和非聚集索引的区别_聚集索引与非聚集索引的总结

    一.索引简介 众所周知,索引是关系型数据库中给数据库表中一列或多列的值排序后的存储结构,SQL的主流索引结构有B+树以及Hash结构,聚集索引以及非聚集索引用的是B+树索引.这篇文章会总结SQL Se ...

  5. mysql的索引的作用_数据库索引的作用,优点和缺点

    为什么要创建索引呢?这是因为,创建索引可以大大提高系统的性能. 第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性. 第二,可以大大加快 数据的检索速度,这也是创建索引的最主要的原因. 第 ...

  6. mysql聚合索引跟非聚合索引的区别_聚集索引和非聚集索引的区别有哪些

    下面说说索引使用的几个误区和问题 第一:聚集索引的约束是唯一性,是否要求字段也是唯一的呢? 分析:如果认为是的朋友,可能是受系统默认设置的影响,一般我们指定一个表的主键,如果这个表之前没有聚集索引,同 ...

  7. java我的世界填充方块_我的世界填充指令 填充TNT的指令是什么

    我的世界填充指令 填充TNT的指令是什么.在我的世界里面有一些指令是具有填充效果的,那下面游戏园小编就给大家将我的世界填充指令介绍一下吧!还有TNT填充指令又是什么都会一一介绍的,那感兴趣的玩家不妨进 ...

  8. python中二维数组如何按索引找元素_按索引或坐标访问二维数组中的元素

    设置 我正在用python编写一个类来处理一个二维的布尔数组.在class Grid(object): def __init__(self, length): self.length = length ...

  9. pandas用众数填充缺失值_数据处理之缺失值填充

    点赞.关注再看,养成良好习惯 Life is short, U need Python 初学Python,快来点我吧 1. 概述 首先对数据缺失的原因.类型以及处理方法做一个简单地总结,如下图所示: ...

  10. 中信所怎么查期刊影响因子_年sci期刊影响因子分区中信所.xls

    您所在位置:网站首页 > 海量文档 &nbsp>&nbsp学术论文&nbsp>&nbsp期刊/会议论文 年sci期刊影响因子分区中信所.xls236页 ...

最新文章

  1. LDD3源码分析之ioctl操作 .
  2. 人工智能时代的用户体验设计与创新
  3. BZOJ4771 七彩树(dfs序+树上差分+主席树)
  4. .net 下语音合成
  5. The executable was signed with invalid entitlements
  6. 工作一年后,我有些感悟(写于2017年)
  7. 【MATLAB统计分析与应用100例】案例006:matlab数据的标准化变换
  8. CNN tensorflow 人脸识别
  9. php持久对象,php-在理论中具有两个外来身份的持久对象
  10. C#利用反射,遍历获得一个类的所有属性名,以及该类的实例的所有属性的值
  11. 第29期:蓝桥杯练习-2022/2/12
  12. 华为交换机配置SSH登录
  13. openGL使用高度贴图模拟地球表面凹凸效果
  14. 上市公司财务报表分析
  15. 读源码(四)—— js Promise
  16. 校园歌手信息评分系统(C语言),大一新生期末实训
  17. 三周年课程促销中奖名单公布!赶紧来看看有没有你!
  18. 世界各国坐标、中国各省会坐标、echars世界各国中英映射和省市区联动数据
  19. 最大不相交子集 POJ1328
  20. java 序列化 文件_一种恢复Java序列化文件数据的方法与流程

热门文章

  1. 怎么查看网站服务器开了哪些端口,怎么查看服务器开了哪个端口
  2. 调出软键盘 挤掉标题栏咋办
  3. 中线提取算法_基于Guided Filter的地形图中线要素提取算法
  4. www.lthack.com php,[经验谈] PHP漏洞全解 ---文章转载自(十八哥,自学it网_公益IT培训)...
  5. 3060ti适配的cuda和cudnn
  6. 国内外优秀计算机视觉团队汇总(2020)
  7. 人类捕杀动物,吃动物就残忍了吗?
  8. sklearn基于轮廓系数来选择n_clusters
  9. rio 10.3 vcl应用更换皮肤
  10. java set方法无法使用_Java setBounds无法与JPanel一起使用