【问题标题】:how to move away from guid fields as primary keys如何摆脱 guid 字段作为主键
【发布时间】:2013-08-31 14:16:33
【问题描述】:

我陷入了困境,想看看我是否能摆脱困境。我有一个数据库,其中包含在 uniqueidentifier 列上定义的表上的所有主键。这有点强迫我们,将“安全”作为原因之一。另一个我认为比较有价值的原因是一些表参与了复制。

我正在审查数据库,我觉得一个很容易避免的未来性能瓶颈是可以在所有表​​中添加自动增量 bigint 列并使其成为主键(集群)。并以某种方式正确地“附加” pk-fk 关系。但仍保留旧列以供将来使用。

在这方面有什么建议/cmets/donots?我们的是 c#/MSSQL Server R2/Linq 环境。

编辑: 看着 cmets,我意识到我遗漏了一些重要的细节。 所有主键 Guid 字段都是集群的,不,我没有使用 newsequentialId(我们使用 Linq to SQL,主键是在客户端生成的。涉及复制时,我们不确定从不同客户端环境正确生成顺序 ID 的方法冲突)。

我的“感觉”是由于已知的事实,即 guid 列上的聚集索引会导致高度碎片化,并且只会随着数据库的增长而恶化。

另外,我现在并没有真正尝试优化,而是尝试纠正一个糟糕的设计,以避免将来在数据库变得太大时出现问题。想知道现在是否值得这样做。

this post 中也与此问题相关的有用讨论,以及 another

【问题讨论】:

  • and I feel one easily avoidable performance bottleneck is to may add auto-increment bigint,一点建议。不要优化感觉。
  • 对您的数据库进行基准测试。使用BIGINT 将数据复制到另一个表,看看性能损失是否真的是个大问题。
  • 附注这对dba.stackexchange.com 可能更好
  • guid 是否用作聚集索引。您使用的是顺序 guid 吗?
  • 我建议您听取@neoistheone 的建议,然后在完成分析后删除聚集索引并选择更合适的列/列集进行聚集。这里也有很多信息stackoverflow.com/questions/277625/…

标签: c# sql-server sql-server-2008


【解决方案1】:

数据库的性能调优实际上很简单,但很难。首先,您需要通过在至少一个工作日(但最好是两个工作日)内运行长时间运行的配置文件来收集针对数据库执行的语句列表。

将该配置文件保存到数据库中以便对其进行查询,这样您就可以轻松找到针对您的数据库执行的DISTINCT 查询。

在确定执行最多的那些之后,分析它们的执行计划,它可能与 GUID 的 无关一切 与查询本身有关(即它们很糟糕)或者你需要一个不同的索引。

注意事项:

  1. 使用WHERE 子句严格过滤的视图。这些都是存储过程或参数化视图的绝佳候选者。
  2. JOIN 对非常大的表的声明,那些有时可能是子查询的良好候选者。这确实取决于执行计划。
  3. 似乎执行多次的语句。这通常是一个很好的迹象,表明应用程序本身并没有很好地管理它往返服务器的频率。我见过会运行相同查询 10 次以上的应用程序。

【讨论】:

  • 谢谢。这很有帮助。当需要进行性能调整时,我会将这些步骤添加到我的待办事项列表中。顺便说一句,我没有收到您对 LievenKeersmaekers 的评论?
  • @Brian,阅读 Eric Lippert 的关于 GUID 的整个系列,blogs.msdn.com/b/ericlippert/archive/tags/guids,该数字让您知道 GUID 是顺序的还是随机的。大多数 GUID 都基于 MAC 地址,因此它们实际上是连续的 - 但这是一个常见的误解。
【解决方案2】:

权宜之计可以是使用 NEWSEQUENTIALID() 而不是 NEWID()。至少这样你不会得到那么多碎片。

创建一个大于任何 GUID 之前生成的 GUID 自 Windows 启动以来,此功能在指定计算机上。后 重新启动 Windows,GUID 可以从较低的范围再次启动,但是 仍然是全球独一无二的。当 GUID 列用作行时 标识符,使用 NEWSEQUENTIALID 可以比使用 NEWID 更快 功能。这是因为 NEWID 函数会导致随机活动 并使用更少的缓存数据页。使用 NEWSEQUENTIALID 也有助于 完全填满数据和索引页面。

http://technet.microsoft.com/en-us/library/ms189786.aspx

请注意,这不一定有助于解决您的性能问题,具体取决于它们是什么(也许您可以详细说明 - INSERTs?SELECT 过滤?等等)。

【讨论】:

  • 我同意。我的评论(在原始问题中)有一个“客户端顺序 uuid”解决方案,以配合这个建议。
【解决方案3】:

通过http://www.sqlskills.com/blogs/kimberly/disk-space-is-cheap/查看 Kimberly Tripp 的建议

她建议按照以下步骤转换为非 GUID 集群键:

如果您的 CL 密钥是 PK,那么您的步骤如下:

Take the database offline (sorry, I’m just the messenger!!)
Disable the FKs
Disable the nonclustered indexes
Drop the clustered PK (alter table)
Optionally, add an identity column?
Create the new clustered index
Create the PK as nonclustered
Enable the nonclustered indexes (alter index…rebuild)
Enable the FKs with CHECK (this is very important)
Bring the database online 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多