首页 > 解决方案 > 非聚集索引包含列导致高碎片

问题描述

我在 Azure SQL Server 中有一个非聚集索引,如下所示:

CREATE NONCLUSTERED INDEX [IX_index_xx] 
ON [dbo].[ActiveDay] ([user_id] ASC, [enterprise_id] ASC)
INCLUDE ([dateTime])  
WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]

当应用程序运行时,它可以在用户执行登录等操作时向该表输入新行或更新“dateTime”列。此表中没有其他繁重的操作。我在表中有大约 135,000 行。我重建了上面的索引,但是 1 天后它又变得碎片化了 60%,页数在 1370 左右。为什么它在 1 天内变得高度碎片化?我真的不明白原因。

标签: sql-serverindexingazure-sql-database

解决方案


为什么它在 1 天内变得高度分散?

此索引中的行按 (user_id,enterprise_id) 排序。因此,当您在表中插入新行时,它可能会位于聚集索引的末尾,但它必须插入到此非聚集索引的中间。如果目标页面已满,则必须对其进行拆分,并且将在此数据库的非完整范围上启动新页面。

来自不同对象的区的交错,以及来自索引排序顺序的不同部分的页面的交错都是碎片的类型。这种非聚集索引的碎片是正常的,通常不是什么大问题,特别是如果您的数据库存储在 SSD 上,就像所有 Azure SQL 数据库一样。

重建索引后,索引中的所有叶页都是 100% 满的,碎片也基本消除了。但是当您向表中插入新行时,碎片自然会返回。在重建之后,任何插入都需要页面拆分,并导致一些碎片。如果您真的想重建索引,您可以将填充因子设置为 80% 左右,以防止在索引重建后出现一连串的页面拆分。


推荐阅读