And*_*all 7 azure-sql-database page-splits accelerated-database-recovery
我在使用 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
from sys.dm_db_index_physical_stats(db_id(), NULL, NULL, NULL, NULL) st
join sys.indexes ix on ix.object_id = st.object_id
and ix.index_id = st.index_id
where object_name(ix.object_id) = 'TestSplit'
and object_schema_name(ix.object_id) = 'dbo';
Run Code Online (Sandbox Code Playgroud)
| 索引名称 | 索引类型描述 | 片段计数 | 页数 |
|---|---|---|---|
| PK_C_dbo_TestSplit_TestSplitId | 聚集索引 | 2 | 第384章 |
现在每隔两行更新一次,将 MyInt 值从 5 更改为 6。
update dbo.TestSplit
set MyInt = 6
where TestSplitId %2 = 1
Run Code Online (Sandbox Code Playgroud)
MyInt 是一个固定宽度的列,因此我希望编辑只是更新页面而不会导致任何页面拆分。然而,页面数量大约增加了一倍,并且片段也遵循页面计数。
| 索引名称 | 索引类型描述 | 片段计数 | 页数 |
|---|---|---|---|
| PK_C_dbo_TestSplit_TestSplitId | 聚集索引 | 第767章 | 第767章 |
通过对诸如Wayne Sheffield - SQL Server 中的页面拆分之类的页面的建议,我可以看到页面拆分肯定是额外页面的原因。
我不明白为什么会发生这种情况或如何阻止它。
我已在本地尝试了所有五个事务隔离级别,但仍然没有页面拆分。我的本地 SQL 服务器是 2017 年 (v14.0.2037.2),我认为加速数据库恢复是在 2019 年推出的。我可以尝试升级本地服务器,但我当然仍然希望阻止实时 Azure 环境中发生的拆分。
Dan Guzman报告了与启用本地 SQL Server 2019 和 ADR 的 Azure SQL 数据库相同的拆分。
经过大量测试,我相信加速数据库恢复是原因。
编辑行时,加速数据库恢复将存储原始行和新行之间的差异。这称为行内版本控制,它允许快速回滚和恢复。
我的表示例是一个非常窄的表,存储 Int 值的差异基本上会使行的大小加倍。这就是为什么我们创建的页面数量几乎增加了一倍(请注意,这些页面也几乎已满)。
Alex Orpwood 已经发现了这个问题并联系了微软。他们回复说这是预期的行为,您可以使用跟踪标志禁用此功能,但他们不推荐它,而且我找不到该标志。
在Azure PAAS SQL Server中,您无法禁用ADR,因此看起来我陷入了这种行为。我只需要在表上使用通常不需要的填充因子,并承受数据库将比本地数据库更大的打击,正如Dan Guzman提到的:
填充因子为 80 将页数减少到 527 (
CREATE UNIQUE CLUSTERED INDEX PK_C_dbo_TestSplit_TestSplitId ON dbo.TestSplit(TestSplitId) WITH(DROP_EXISTING=ON,FILLFACTOR=80);)。
| 归档时间: |
|
| 查看次数: |
245 次 |
| 最近记录: |