标签: page-splits

SQL Server 中的 B 树节点拆分策略用于单调递增值

考虑一个总是单调增加的值的 B 树索引,例如 IDENTITY 类型的列。使用传统的 B 树实现,每当节点已满时,它将被拆分 50%/50%,我们最终得到一个 B 树,其中(几乎)所有节点都只有 50% 已满。

我知道 Oracle 会发现值何时不断增加,在这些情况下,Oracle 会执行 90%/10% 的拆分。这样,(几乎)所有节点都将充满 90%,并且对于这些非常常见的情况,可以获得更好的页面利用率。

我无法在 SQL Server 中找到类似功能的文档。但是,我进行了两次实验,分别在索引中插入了 N 个随机整数和 N 个连续整数。前一种情况使用了更多的页面,后者。

SQL Server 是否提供类似的功能?如果是这样:你能指点我一些关于这个功能的文档吗?

更新: 通过下面提供的实验,似乎叶节点保持未分裂,内部节点分裂 50%/50%。这使得增加键上的 B 树比随机键上的更紧凑。然而,Oracle 的 90%/10% 方法甚至更好,我仍然在寻找一些官方文档来验证实验中看到的行为。

index sql-server fragmentation page-splits

8
推荐指数
1
解决办法
1334
查看次数

MS SQL 页面拆分混乱

我对 MS SQL 中的页面拆分有点困惑,我正在寻找明确的答案。这个故事似乎有两个版本:

1 - Fillfactor 仅影响创建/重建索引时的完整页面。页面拆分始终为 50/50

2 - Fillfactor 也会影响页面的分割方式。因此,如果有 70% 的填充因子并且页面溢出,它将拆分 70/30

非常感谢

index sql-server page-splits fill-factor

8
推荐指数
1
解决办法
586
查看次数

更新 Azure SQL Server 中的行导致意外的页面拆分

我在使用 Azure SQL Server PAAS 的实时环境中遇到了很多我不理解的页面拆分。正在发生的更新不应增加行的大小,因此永远不会导致页面拆分。此外,该行为仅发生在 Azure 中,不会发生在本地 SQL 实例上。

我使用的是使用 eDTU 定价和标准层 (200 eDTU) 的 Azure 弹性池。

我创建了以下示例来演示:

create table dbo.TestSplit
(
    TestSplitId int not null identity,
    MyInt int not null,
    
    constraint PK_C_dbo_TestSplit_TestSplitId primary key clustered (TestSplitId)
);
Run Code Online (Sandbox Code Playgroud)

插入 100,000 行且 MyInt = 5:

insert into dbo.TestSplit
(MyInt)
select top(100000) 5
from sys.columns AS a 
cross join sys.columns AS b 
cross join sys.columns AS c
Run Code Online (Sandbox Code Playgroud)

运行以下 SQL 显示已创建 384 个页面,并且有 2 个碎片。

select
    ix.name as index_name,
    st.index_type_desc,
    st.fragment_count,
    st.page_count …
Run Code Online (Sandbox Code Playgroud)

azure-sql-database page-splits accelerated-database-recovery

7
推荐指数
1
解决办法
245
查看次数

索引页面(页面类型 2)

我试图了解 SQL Server 中的页面拆分,阅读什么是页面拆分发生什么了?为什么会这样?为什么要担心?通过托尼·罗杰森

CREATE TABLE mytest
  (
     something_to_see_in_data CHAR(5) NOT NULL CONSTRAINT pk_mytest PRIMARY KEY CLUSTERED,
     filler                   VARCHAR(3000) NOT NULL
  ) 

go

insert mytest ( something_to_see_in_data, filler ) values( '00001', replicate( 'A', 3000 ) )
insert mytest ( something_to_see_in_data, filler ) values( '00002', replicate( 'B', 1000 ) )
insert mytest ( something_to_see_in_data, filler ) values( '00003', replicate( 'C', 3000 ) )
go
Run Code Online (Sandbox Code Playgroud)

要检查我的表的页面:

DBCC IND ( 0, 'mytest', 1);
Run Code Online (Sandbox Code Playgroud)
CREATE TABLE mytest …
Run Code Online (Sandbox Code Playgroud)

index sql-server database-internals page-splits

6
推荐指数
1
解决办法
941
查看次数

降低填充因子会导致更多的页面拆分吗?

我们一直遇到一个表上的页面拆分问题,这是一个特别麻烦的问题 - 它是数据库中活动的审计日志,并且已经增长到 1TB 以上。主要索引位于记录类型上,它是 an NVARCHAR(100)- 因为当有 5 种记录类型时您需要它 - 它比 aTINYINT和记录 id更有意义- 它是 anNVARCHAR(200)而不是记录的整数键。

它们还涵盖索引,包括键、旧值、新值等——非常广泛。

这是一个旧系统,不幸的是,这种审计的代码无处不在,而不是集中在一个程序中。它无法改变,我们正在经历漫长的微服务重写的痛苦过程。

因此,我将两个索引的填充因子从 100% 降低到 85%。

并且页面拆分变得更糟。我会说大约 3 倍的页面拆分。

这是一个普遍的结果吗?大多数建议说减少填充因子以提高页面拆分性能。我可以理解为什么它会这样做,因为键中数据的宽度。

建议是进一步降低填充因子,还是将其恢复原状?

page-splits fill-factor sql-server-2014

5
推荐指数
2
解决办法
139
查看次数