代码之家  ›  专栏  ›  技术社区  ›  Shehan Simen

非聚集索引include列导致高碎片

  •  0
  • Shehan Simen  · 技术社区  · 5 年前

    我在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]
    

    当应用程序运行时,它可以在此表中输入新行,或者在用户执行某些操作(如登录)时更新“日期时间”列。此表中没有其他繁重的操作。我桌上有大约135000行。我重新构建了上面的索引,但是1天后它又变得支离破碎,60%的页面数在1370左右。为什么一天之内它会变得非常零碎?我真的不明白原因。

    0 回复  |  直到 5 年前
        1
  •  0
  •   David Browne - Microsoft    5 年前

    为什么一天之内它会变得非常零碎?

    此索引中的行按(用户标识、企业标识)排序。因此,当您在表中插入新行时,它可能会进入 结束 但它必须插入到 中间的 这个非聚集索引。如果目标页已满,则必须将其拆分,并且此数据库的新页将以非完整的范围启动。

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

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