这实际上是一个非常复杂的主题。 开启 PAD_INDEX 会对大型表中的读取性能和内存压力产生显着影响。表越大,效果越大。作为一项规则,我会说你想把它关掉,除非你属于一些不常见的类别。然后,仔细遵循此建议。正如我在下面的示例中所示,当 PAD_INDEX 为 ON 时调整 FILLFACTOR 可能会产生指数效应,需要仔细平衡。
- PAD_INDEX 总是对读取产生不利影响! FILLFACTOR 越低效果越大,所以在开启时需要密切注意 FILLFACTOR 的值。在大型表上,您基本上停止考虑 FILLFACTOR 减少叶分裂,并开始考虑它对中间膨胀与中间分裂的影响。
- PAD_INDEX 很少对少于 100,000 行的索引产生有用的影响,并且永远不会对覆盖标识或插入时间类型列的索引产生积极影响,因为插入总是到表的末尾。
- 从上面您应该看到,如果您打开 PAD_INDEX,您必须仔细平衡负面影响与正面影响。
经验法则:PAD_INDEX 很少用于:
- 非聚集索引 - 除非它们很宽。
- 关于非常窄的表的聚集索引。
- 在行数少于 100K 的表上 - 除非插入是高度聚集的,即使这样也可能存在问题。
您必须了解它的工作原理:
当您插入索引时,该行必须适合包含适当范围的键的叶块。聚集索引的行通常比非聚集索引宽得多,因此它们的叶块包含更少的行。 FillFactor 为叶子中的新行创建空间,但在非常宽的行或大量插入聚集在一起而不是均匀分布的情况下,创建足够的松弛(1-pct 填充)以防止分裂通常是不切实际或不可能的。
当发生拆分时,将创建一个新的中间行以指向新块,并且该行必须适合其相应的块。如果该中间块已满,则必须首先对其进行拆分。如果你特别不走运,分裂可以一直运行到根。当根分裂时,您最终会创建一个新的索引级别。
PAD_INDEX 的目的是在中间级别的块中强制使用最少的可用空间。
重建后,较低级别的空间可能很少或没有。因此,如果您有很多叶子分裂并且 PAD_INDEX 没有打开,那么您可以在整个地方大量分裂中间体!
但大多数情况下,可以使用 FILLFACTOR 管理拆分。更大的拆分问题发生在插入模式上,它几乎可以保证您没有足够的可用空间,然后打开 PAD_INDEX 通过提供更深层次的空间来帮助缓解这种情况,因此当确实发生拆分时,您不太可能招致大量的多级拆分。
示例案例
我有一个包含 100K 行的客户表。在任何一天,我的客户中约有 5% 是活跃的。我有一张按时间记录客户活动的表格。客户平均执行 20 次操作,而描述平均需要 1K。所以我收集了 100MB 的数据,并假设我已经有一年在表中 - 所以 36GB。
该表插入了 1Kb 行,其中 key 列的 customer_number 和 insert_time(按此顺序)。显然,普通客户会在插入他们预期的 20 行时多次拆分 8K 叶块,因为每一行将立即插入同一块中的前一行之后,直到它拆分、拆分和拆分(使人们认为只有非集群的堆索引...)。如果指向适当叶子的中间块没有足够的空间容纳至少 4 行(实际上可能是 8 行但是......),则中间块将需要拆分。鉴于此示例的密钥占用 22 个字节,一个中间块可以容纳 367 个条目。这意味着我的中间块需要 6% 的可用空间或 94% 的填充空间来容纳 4 个条目。
请注意,即使是 1% 的 FILLFACTOR 也不会阻止叶块拆分,因为一个块只能容纳 8 行。将 FILLFACTOR 设置为 80% 将只允许在叶拆分之前添加 1 行,但如果 PAD_INDEX 开启,则每个中间块将注入超过 800 字节的可用空间。当我只需要 88 个时,每个中间块大约有 800 个空字节。
这真的很重要!:所以如果我的表中已经有 36M 行,使用 80% 意味着每个中间块有 294 行,这意味着 122K 块,这意味着我已经将 98MB 注入到我的中间块中块结构,当 94% 让每个块适合 345 行时,因此只有 104K 中间块(是的,为了简单起见,我省略了较低的级别)。将 88 字节添加到 104K 块中的每个块只会增加 9.2MB,而不是 98MB。
现在考虑一下,我的客户中只有 5% 做了任何事情。有些做了超过 20 件事情,有些做的更少,所以无论如何都会拆分一些块,因为实际上只需要 275KB 来保存当天的索引行 (100k/8*22),最好的情况是我的 9.2MB 中只有 8.9MB 是死气沉沉的.如果防止分裂很重要,那么 9mb 非常值得,但我会更加努力地考虑 98mb。
因此,通过打开 PAD_INDEX,我应该完全放弃控制叶分裂并转向控制中间分裂。
除了第一个中级,别担心!任何聚类(在本例中是 customer_number 的聚类)都会引发蝴蝶效应,这会将您所做的任何计算抛出窗外。除非你的插入是完全一致的,否则你在找到合适的数字来平衡膨胀和分裂的误差通常远大于较低级别块空间的影响。