在这种情况下,为什么要将fillfactor设置为较低的值?

时间:2016-04-11 19:32:25

标签: sql-server indexing

我们假设我们有一个使用SQL Server的OLTP系统。我们假设我们在表格上有一个聚集索引。

请给我一些以下问题的答案:

如果您只插入遵循索引顺序的新记录,那么页面拆分将仅限于上次索引重建时存在的最后一页上或之后的页面,对吗?

换句话说,如果您只插入遵循索引顺序的新记录,那么在您最后一次索引重建时存在的最后一页之前(顺序)位于的任何页面中都不会发生页面拆分,对吗?

也就是说,只要您不尝试将记录插入现有索引的中间,就不会导致页面拆分发生在最后一页存在于上一页之前的任何页面中index rebuild,对吗?

如果以上都是真的,那么通常你也常常避免将记录插入到现有索引的中间吗?我的意思是,你什么时候想做这样的事情?

我问这些问题,因为我无法理解为什么有人会决定为OLTP系统上的索引设置一个fillfactor值。我的想法是"如果你没有计划通过在现有索引的中间插入记录来搞乱索引,那么在每个索引页面和数据页面中保留所有未使用的空白空间的重点是什么呢?永远不会被填满?"

我知道页面拆分将从最后一页(顺序)开始 - 在最后一次索引重建时存在 - 从此开始。但是,您能否详细解释为什么有人会选择将fillfactor设置为OLTP系统的低值,而您没有计划将记录插入现有索引的中间?

如果我在理解这一切是如何运作的时候遗漏了什么,请告诉我。

感谢。

3 个答案:

答案 0 :(得分:1)

您对browser.executeScript(function () { return window.angular.element(document.body) .find('test-directive').controller('testDirective'); }).then(function (directiveControllerInstance) { console.log(directiveControllerInstance); }); 的理解符合我的理解。

  

如果以上都是真的,那么通常你也常常避免将记录插入到现有索引的中间吗?我的意思是,你什么时候想做这样的事情?

当您不使用顺序密钥时。如果所有聚簇索引都是FILLFACTOR个字段,那么请确定。但是,对于整个数据库中的每个表,情况可能并非如此。如果您有多对多关系的联结表,那么您可以随时添加关系。您probably根本不希望该表在该表中包含IDENTITY(1,1)键。如果您反而聚集在表格中的外键的复合主键上 - 因为当您加入了您将要使用的内容时 - 那么您就不会使用顺序插入一点都不。

此外,即使您使用顺序密钥,即使您使用,也可能不会集中在它们上。在IDENTITY列以外的其他内容上进行聚类是可能的,并且通常是可取的。这将取决于您计划如何使用您的数据。如果您要存储事件但又知道要将每个站点的事件保存在一起,因为这是您在90%的时间内查询事件的方式,那么您可能会在群集密钥中包含事件站点。

答案 1 :(得分:1)

一个有点人为的情况是,如果行锁升级到页锁,那么受影响的行越少,因为每页的行数越少。虽然如果没有发生DML,所有锁都应该是共享锁,因此是兼容的。

另一种情况是,如果您更新一行,使其不再适合页面。想象一下下表:

create table foobar (
   a int identity primary key clustered,
   b varchar(1000) default 'a'
);

现在,如果我这样做:

insert into foobar default values
go 1000

我可以在一个页面上获得所有这些行(或多或少 - 假设填充因子为100,每行将占用4 + 1 = 5个字节。我知道有行开销,但让我们做演示简单)。但是,如果我这样做了:

update foobar 
set b = replicate('a', 1000);

现在每行占用4 + 1000 = 1004字节,每页只能容纳7行。我需要更多页面!但是,如果填充因子最初设置得较低,我可能仍然会产生一些页面拆分(除非填充因子设置为只有1行/页),但更少。如果您使用的是SQL 2008或更高版本,我邀请您通过扩展事件进行探索 - 有一个页面拆分事件。

TL; DR - 更新也会导致页面拆分。

答案 2 :(得分:1)

是的,当附加到索引时,fillfactor无效。

是的,以导致页面拆分的方式写入索引的中间位置并不是一件好事。

您无法始终附加到索引。当您将用户注册索引到Web论坛时,用户将以随机顺序输入:电子邮件,用户名,电话,电子邮件激活密钥。 (也会有顺序插入,例如ID和注册日期。)

在这里,你唯一的选择是如何缓解(如果有的话)。

  

为什么有人会选择将fillfactor设置为低值,而OLTP系统中你没有计划将记录插入现有索引的中间位置?

实际上,我不会这样做,但这样的纯OLTP系统很少存在。

这是以不同顺序呈现数据的索引点。并非所有有趣的订单都是相互一致的。