【问题标题】:SQL Server Performance and clustered index valuesSQL Server 性能和聚集索引值
【发布时间】:2009-05-25 14:23:20
【问题描述】:

我有一个带有唯一聚集索引 myId 的表 myTable,填充因子为 100% 它是一个整数,从零开始(但它不是表的标识列) 我需要向表中添加一种新类型的行。 如果我可以通过使用 myId 的负值来区分这些行,那可能会很好。

负值会导致额外的页面拆分并减慢插入速度吗?

额外背景: 该表作为数据仓库的 etl 的一部分存在,该数据仓库从不同的系统收集数据。我现在想容纳一种新型数据。我这样做的一种方法是为这些新数据保留负 ID,因此将自动聚类。这也将避免架构中的主要键更改或额外列。

答案总结: 100% 的填充系数通常会减慢刀片的速度。但不是顺序发生的插入,包括顺序否定插入。

【问题讨论】:

  • 100% 填充因子绝对不是聚簇索引的好选择,正如 Mitch 所述 - 但这与正或负 INT 值无关。

标签: sql-server performance clustered-index


【解决方案1】:

除了您已经获得的实际管理要点和可疑使用负 id 来表示数据模型属性之外,这里还有一个有效的问题:给出一个 int id 从 0 到 N 的表,在哪里插入新的负值这些价值消失了,它们会导致额外的分裂吗?

初始行将放置在聚集索引叶页上,id 为 0 的行位于第一页,id 为 N 的行位于最后一页,填充中间的页面。当插入值为 -1 的第一行时,这将排在 id 为 0 的行之前,因此将向树中添加一个新页面(实际上将分配 8 个页面的范围,但这是不同的点)和将链接页面放在叶级链接列表前面的页面。这不会导致前第一页的页面拆分。在进一步插入值 -2、-3 等时,它们将转到同一个新页面,并且它们将被插入到正确的位置(-2 在 -1 之前,-3 在 -2 之前等),直到页面填满。进一步的插入将在该页面之前添加一个新页面,该页面将容纳更多的新值。正值 N+1、N+2 的插入将进入最后一页并放入其中直到填满,然后它们将导致添加新页面并开始填充该页面。

所以基本上答案是这样的:在聚集索引的任一端插入都不应该导致页面拆分。页面拆分只能由 两个现有键之间插入。这实际上也扩展到非叶页面,集群两端的索引也可能不会拆分非叶页面。当然,我在这里不讨论 更新 的影响(如果增加可变长度列的长度,它们可能会导致拆分)。

最近在 SQL Server 博客圈中关于页面拆分的潜在性能问题的讨论很多,但我必须警告不要采取不必要的极端来避免它们。页面拆分是一种正常的索引操作。如果您发现自己处于插入期间页面拆分性能影响可见的环境中,那么“缓解”措施可能会给您带来更严重的打击,因为您将创建人为的页面闩锁热点,这些热点要糟糕得多影响每个插入。 正确的是,频繁拆分的长时间操作会导致高度碎片化,从而影响数据访问时间。我说最好通过非高峰期定期索引维护操作(重组)来缓解这种情况。避免过早的优化,始终先测量。

【讨论】:

  • 这可能最接近回答我脑海中的问题并且我最终进入了页面
【解决方案2】:

对于任何合理的系统来说都不足以引起注意。

当页面已满时会发生页面拆分,无论是在范围的开头还是结尾。 只要你定期维护索引...

在填充因子 cmets 之后编辑:

使用 90 或 100 FF 拆分页面后,每个页面将占满 50%。 FF = 100 仅表示插入会更快发生(可能是第一次插入)。

使用严格单调递增(或递减)的键(+ve 或 -ve),页面拆分发生在范围的任一端。

但是,来自 BOL,FILLFACTOR

填充

将数据添加到表的末尾

除 0 或以外的非零填充因子 100 对性能有好处,如果 新数据均匀分布 整个桌子。然而,如果所有 数据被添加到末尾 表,索引中的空白空间 页面不会被填满。例如, 如果索引键列是 IDENTITY 列,新行的键总是 增加并且索引行是 逻辑上添加到末尾 指数。如果现有的行将 更新的数据延长了 行的大小,使用填充因子 小于 100。每个上的额外字节 页面将有助于最小化页面拆分 由行中的额外长度引起。

那么,对于严格单调的键,填充因子是否重要...?尤其是在低容量写入时

【讨论】:

  • 填充因子是这个答案之后的补充
【解决方案3】:

不,一点也不。负值与正值一样有效。没问题。基本上,在内部,它们都是 4 个字节的 0 和 1 :-)

马克

【讨论】:

  • 填充因子是这个答案之后的补充
  • 非常。该问题与负聚集索引值无关。问题应该是“我会得到 100% 填充因子的页面拆分”吗?答:是的。
【解决方案4】:

你问错问题了!

如果创建填充因子为 100% 的聚集索引,则每次插入、删除甚至修改记录时,都可能发生页面拆分,因为现有索引数据页面上可能没有空间来写入更改。

即使定期维护索引,100% 的填充因子在您知道将要执行插入的表上也会适得其反。更常见的值是 90%。

【讨论】:

  • 同意 - 你提出了一个很好的观点。然而,这与您存储的是正值还是负 INT 值完全无关.....
  • 插入通常是附加的,即具有大于现有值的 myID 值。在这种情况下,页面创建的行为是否不同?
  • @cindi。不,在重建的聚集索引上,无论如何你都会得到页面拆分。
  • 发生页面拆分,每个页面都占满 50%。 90 对 100 只决定它发生的时间。无论如何,严格单调的关键可能会有所不同:请参阅我的更新答案
【解决方案5】:

我担心这篇文章可能走错了方向,因为这里似乎存在一个潜在的设计问题,无论结果是什么页面拆分。

为什么需要引入否定 ID?

例如,一个整数主键应该唯一标识一行,它的符号应该是无关紧要的。如果不是这种情况,我怀疑您的表的主键可能存在定义问题。

如果您需要标记/识别新插入的记录,请为此专门创建一个列。

此解决方案将是理想的,因为您可以确保您的主键是顺序的(也许使用身份数据类型,虽然不是必需的),从而完全避免页面拆分(插入时)的问题。

另外,为了确认是否可以,聚集索引主键(例如标识整数)的填充因子为 100%,不会导致顺序插入的页面拆分!

【讨论】:

    猜你喜欢
    • 2011-03-24
    • 2014-10-04
    • 1970-01-01
    • 2013-03-22
    • 1970-01-01
    • 2011-10-12
    • 2014-04-27
    • 2011-09-18
    • 2018-01-19
    相关资源
    最近更新 更多