【发布时间】:2016-05-23 16:16:15
【问题描述】:
我的公司犯了在我们的 Azure SQL 数据库表上使用 GUID 作为主键的罪行(实际上比这更糟糕:我们使用 VARCHAR(36) 而不是 UNIQUEIDENTIFIER)。因此,我们最终得到了碎片索引。他们看起来像这样:
CREATE TABLE OldTable (
Id VARCHAR(36) PRIMARY KEY CLUSTERED NOT NULL DEFAULT NEWID(),
CreateTime DATETIME2 NOT NULL,
...
)
我通过创建新表“修复”了这个问题。这一次,我为 CLUSTERED INDEX 使用了一个不可变的、不断增加的 DATETIME2(例如 CreateTime)列,并将 VARCHAR(36) 保留为 PRIMARY KEY,但这次是非集群的。像这样:
CREATE TABLE NewTable (
Id VARCHAR(36) PRIMARY KEY NONCLUSTERED NOT NULL DEFAULT NEWID(),
CreateTime DATETIME2 NOT NULL INDEX IX_NewTable_CreateTime CLUSTERED,
)
然后我使用 INSERT INTO NewTable SELECT * FROM OldTable 将旧表中的行“复制”到新表。最后,我重命名了表并删除了旧表。生活似乎很美好。
令我惊讶的是,几周后,我发现 NewTable 有很多碎片索引,平均碎片率高达 80%!甚至 IX_NewTable_CreateTime 也报告了 18% 的碎片。
INSERT INTO 是否使索引碎片化? REBUILD 索引会永久解决问题吗?
【问题讨论】:
-
碎片是不可避免的,随着时间的推移索引会被碎片化。你必须重建索引,因为 SQL azure 不会为你做这件事
标签: sql-server azure azure-sql-database clustered-index