Bru*_*oLM 135 performance sql-server primary-key uniqueidentifier
我一直在阅读使用或不使用Guid和的原因int。
int更小、更快、更容易记住、保持时间顺序。至于Guid,我发现的唯一优点是它是独一无二的。在哪种情况下 aGuid会更好int,为什么?
从我所看到的,int除了数量限制之外没有任何缺陷,这在许多情况下是无关紧要的。
究竟为什么被Guid创造?我实际上认为它除了用作简单表的主键之外还有其他用途。(任何Guid用于某事的实际应用程序的示例?)
SQL Server 上的 ( Guid = UniqueIdentifier ) 类型
Cod*_*awk 120
Jeff 的帖子解释了很多关于使用 GUID 的利弊。
###GUID 优点
- 每个表、每个数据库和每个服务器都是唯一的
- 允许轻松合并来自不同数据库的记录
- 允许跨多个服务器轻松分发数据库
- 您可以在任何地方生成 ID,而不必往返数据库,除非需要部分顺序性(即使用
newsequentialid())- 大多数复制方案无论如何都需要 GUID 列
###GUID 缺点
- 它比传统的 4 字节索引值大 4 倍;如果您不小心,这可能会对性能和存储产生严重影响
- 调试麻烦 (
where userid='{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}')- 生成的 GUID 应该是部分顺序的以获得最佳性能(例如,
newsequentialid()在 SQL Server 2005+ 上)并启用聚集索引
如果您确定性能并且不打算复制或合并记录,则使用int,并将其设置为自动增量(SQL Server 中的标识种子)。
rmi*_*lle 27
我成功地使用了混合方法。表包含两个自动增量主键整数id列和一guid列。将guid根据需要全局唯一标识该行并且可以使用id可用于查询,排序和行的人的识别。
TML*_*TML 22
如果您将数据与外部源同步,持久的 GUID 会好得多。我们使用 GUID 的一个快速示例是一种工具,它被发送给客户以抓取他们的网络并执行某些类别的自动发现,存储找到的记录,然后将所有客户记录集成到中央数据库中回到我们这边。如果我们使用整数,我们将有 7,398 个“1”,而且要跟踪哪个“1”是哪个会困难得多。
我在这个线程上看到了很多关于随机 GUID 的典型答案以及像 NEWSEQUENTIALID() 这样的东西来拯救世界。是的,我确实同意任何形式的 GUID 都很大,但这实际上是它们唯一的问题。我会告诉你,随机 GUID 并不是“被证明”的那样的碎片问题。在可能是您见过的有关 SQL Server 的最异端的演示中,我证明随机 GUID 碎片实际上是一个由于测试不足和错误信息而长期存在的神话。事实证明他们不是问题……我们才是问题!
总结一下如何防止数百万个插入的 GUID 碎片......
由于分布均匀,当碎片达到大约 1% 时,您就处于表中几乎所有页面上同时发生大量碎片的边缘。当逻辑碎片超过 1% 时,您必须采取行动。
您需要采取的操作是在填充因子之上创建自由空间。这意味着您不能使用 REORGANIZE,因为它无法创建额外的页面来展开索引以使可用空间高于填充因子。事实上,重新组织压缩页面直至填充因子。换句话说,它会尽力在最坏的情况下删除尽可能多的可用空间。相反,您必须使用 REBUILD 来代替。
事实证明,由于压缩,REORGANIZE 实际上会导致碎片并使其永久化。事实证明,实际上最好不要做任何索引维护,而不是做错事,而 REORGANIZE 所做的索引压缩是完全错误的,因为它无法在填充因子之上创建可用空间来阻止碎片。如果您是 24/7 或使用标准版,无法进行在线重建,那么请等待维护期。
此外,REORGANIZE 被宣传为比 REBUILD 占用的资源少得多。实际上并非如此,尤其是当您降低填充因子以防止碎片(即使在非 GUID 索引上)时。
我同意,由于我们多年来所接受的教育,这一切似乎都是不可能的。这是我制作的演示文稿的最后一张幻灯片,显示了 GUID 聚集索引(参见图例)的一年历史,使用预排序 GUID 作为不断增加的基线,没有碎片,没有索引维护的随机 GUID,以及具有 3 种不同的随机 GUID以每天 10 万行的插入速率使用 1%“低阈值”重建的填充因子。
下面的一张幻灯片显示了 REORGANIZE 对日志文件的影响有多么糟糕。红线是所谓的“最佳实践”线,图表最底部的小绿线是 1%“低阈值”重建线。
如果您想观看演示,请观看以下视频,在该视频中,我打破了随机 GUID 碎片的神话,并浪费了所谓的“最佳实践”索引维护,世界上 98% 的人在过去 22 年里都犯了错误年。然后,还要了解有关索引维护的经验教训也适用于其他类型的索引。
这是视频链接。作为对那些戴着耳机的人的警告,他们在 15:00、30:15 和 45:25 时间戳插入了一些突然出现的响亮广告,以“支付账单”以维持 GROUPBY.org 的运行。
这是链接。
Black Arts Index 维护 1.2 - 指南与碎片
rmirabelle 的答案就是我所做的。然而,对于较大规模的项目,有一个最终设计,两者都可以使用:
用途:按键映射表
TableA.ID 在数据库中本地用作主键以及用于 JOINing 的键。TableAMap.ID 与TableA.ID 相同,TableAMap.UniversalID 仅用于系统之间。
TableA
- ID int (PK)
- Data varchar(100)
TableAMap
- ID int (PK)
- UniversalID GUID (Indexed - nonclustered)
Run Code Online (Sandbox Code Playgroud)
数据库复制/导入/导出很少需要 GUID。因此,不再将 GUID 放在主表上,因为它每行占用额外的 8 个字节,并且 GUID 索引将(默认情况下)存储在同一卷上;一个单独的表(又名标准化)可以解决这个问题。
有了单独的表,您的 DBA 就可以将其存储在另一个速度较慢的磁盘上。此外,如果仅某些批处理作业需要 GUID,您可以在需要之前创建 GUID 索引,然后将其删除。
另外,当然可以简单地将UniversalID 添加到TableA,而不是添加TableAMap 等扩展表。