【问题标题】:Nonclustered index include column causes high fragmentation非聚集索引包含列导致高碎片
【发布时间】:2019-04-04 00:38:50
【问题描述】:

我在 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-server indexing azure-sql-database


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 嗨,大卫,感谢您提供的信息。我一直认为,如果某些聚集索引的碎片率达到 97%,那么它确实会减慢一些查询。我遇到过一些查询需要 6 分钟才能返回的情况,一旦我重建这些非聚集索引,它们会在 3 秒内返回。那么如果我不能完全依赖这个碎片百分比,我怎么能在非聚集索引中使用这个碎片信息呢?
    • 重建索引会更新统计信息,这会影响所选的查询计划。在 Azure SQL 数据库中,忽略并依赖自动优化是安全的,至少在最初是这样。 docs.microsoft.com/en-us/azure/sql-database/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-17
    • 2011-05-29
    相关资源
    最近更新 更多