目前,我们有许多在主键上使用 newid() 的表。这导致了大量的碎片。因此,我想将列更改为使用 newsequentialid() 。
我想现有数据将保持相当碎片化,但新数据将不那么碎片化。这意味着在将 PK 索引从非集群更改为集群之前,我可能应该等待一段时间。
我的问题是,有人有这方面的经验吗?有什么我忽略的事情需要注意吗?
目前,我们有许多在主键上使用 newid() 的表。这导致了大量的碎片。因此,我想将列更改为使用 newsequentialid() 。
我想现有数据将保持相当碎片化,但新数据将不那么碎片化。这意味着在将 PK 索引从非集群更改为集群之前,我可能应该等待一段时间。
我的问题是,有人有这方面的经验吗?有什么我忽略的事情需要注意吗?
您可能会考虑使用comb guids,而不是newsequentialid。
cast(
cast(NewID() as binary(10)) +
cast(GetDate() as binary(6))
as uniqueidentifier)
Comb guid 是纯随机 guid 与当前日期时间的非随机性的组合,因此连续几代的梳 guid 彼此靠近,并且通常按升序排列。与 newsequentialid 相比,Comb guid 具有多种优势,包括它们不是黑盒、可以在默认约束之外使用此公式以及可以在 SQL Server 之外使用此公式的事实。
如果您切换到顺序引导并同时重新组织一次索引,您将消除碎片。我不明白你为什么要等到碎片化的页面链接在连续范围内重新排列。
话虽如此,您是否进行了任何测量以表明碎片实际上正在影响您的系统?仅查看索引并看到“碎片化 75%”并不意味着访问时间受到影响。还有更多因素在起作用(缓冲池页面的预期寿命、读取与写入的速率、顺序操作的位置、操作的并发性等)。虽然从 guid 切换到顺序 guid 通常是安全的,但您仍然可能会引入问题。例如,您可以看到插入密集型 OLTP 系统的页面锁存器争用,因为它创建了一个插入累积的热点页面。
谢谢你,yfeldblum!您对 COMB GUID 的简单明了的解释确实帮助了我。我实际上正在考虑做这篇文章的相反操作:我不得不摆脱依赖,newsequentialid()
因为我试图将 SQL Server 2012 db 迁移到 Azure,并且newsequentialid()
那里不支持该功能。
我能够使用以下语法将我的所有表 PK 默认值更改为 COMB GUID:
ALTER TABLE [dbo].[Company]
ADD CONSTRAINT [DF__Company__Company_ID__72E6D332]
DEFAULT (CONVERT([uniqueidentifier],CONVERT([binary](10),newid(),0)+CONVERT([binary](6),getdate(),0),0)) FOR [CompanyId]
GO
我的 SQL2012 数据库现在愉快地生活在 Azure 云中。
如果这是 SQL Server,您将通过调用 newid() 生成 Guid。这对主键不利。使用整数标识列作为主键,并使您的 Guid 成为代理键(和行 guid 列)。