【问题标题】:SQL Server 2008 Table Structure with Guid Performance Considerations具有 Guid 性能注意事项的 SQL Server 2008 表结构
【发布时间】:2011-11-17 03:16:47
【问题描述】:

我现在实际上在是否使用 Guid 方面处于两难境地。

我有一个名为 Posts 的非事务性表,其 PK 为 bigint。

据我了解,使用 Guid 作为 PK 会影响查询性能。但是,为了使查询字符串真正唯一,我决定添加一个名为specialIDGuid default value newid() 的列。这将使我的所有查询字符串真正独一无二,因为我需要做的就是执行以下查询:

SELECT * 
  FROM Posts p 
 WHERE p.specialID = '[query-string]'; // For single record retrieval

至于 Joins,bigint PK 将发挥如下作用:

SELECT p.id, p.specialID, ul.name as Writer 
  FROM Posts p 
  JOIN Users ul ON ul.id = p.writer;

但是,我的同事不同意,并说它仍然会影响查询性能。为什么?我应该继续这样吗?真正唯一的查询字符串不是必需的,但会是首选。如果它确实会影响性能,我们如何才能拥有一个真正唯一的查询字符串?

【问题讨论】:

  • 数据类型越窄,性能越好。 INT 而不是 BIGINT 等。你有数据来证明 BIGINT 的需要吗?我需要进一步了解为什么需要使用 GUID,因为如果设计需要,性能并不重要。
  • 你好 OMG Ponies,[编辑,似乎 Enter 只会提交] 我使用 bigint 而不是 int,因为我预计记录会随着时间的推移而增长,这将是巨大的。 Guid 的原因就像陈述的那样,我希望它是一个真正唯一的查询字符串。例如,如果我要访问 id 为 100 的帖子,而不是 Post.aspx?id=100,我可以使用 Post.aspx?id=[Guid]
  • 在获得数据之前,您可以使用 INT。 “真正唯一的查询字符串” - 您的示例是主键,当 IDENTITY 以一小部分开销提供相同功能时,不需要使用 GUID。使用 GUID 作为 GET 参数也比数值更可能是 SQL 注入攻击向量。更长的时间,它也是 URL 长度的一个问题。
  • 使用 GUID 作为 SQL Server 中的 集群键(数据物理排序的键)是一个非常糟糕的选择,因为存在碎片和其他性能问题。否则,拥有一个 GUID 列并没有那么糟糕。所以我会说继续前进,在其上放置一个索引(使其成为唯一索引)并密切关注性能 - 但我预计不会有任何重大/可衡量的负面影响
  • 至于“用尽INT标识值”:如果您使用从1开始的INT IDENTITY,并且您每秒、每天、全年插入一行,则需要66.5 年,距离你达到 20 亿的上限 ....

标签: sql sql-server sql-server-2008 primary-key guid


【解决方案1】:

它不应该显着妨碍 SELECT 查询,尤其是如果您正确索引该列。它可能会影响插入,但如果 GUID 不是聚集索引的一部分,则问题不大。它还会影响存储需求,具体取决于您要存储的数据量,因为它(显然)要大得多。

详细的讨论在这里:http://www.sql-server-performance.com/2005/guid-performance/ 虽然那是针对 2005 年的,但我相信所有观点仍然有效。

** 编辑:简单的索引示例 ** “覆盖索引”仅表示您有一个包含相关列的索引。聚集索引意味着记录实际上是按照索引所说的顺序存储的,非聚集索引意味着索引持有指向存储位置的指针。考虑一下字典与书籍索引之类的区别。字典按字序排序,并按该顺序(聚集)存储其所有数据,而索引按字序排序,但有一个指向不同顺序的页码的指针(非聚集)。

因此,要为您的列创建索引,您可以:

CREATE INDEX idx_posts_specialId
    ON Posts (specialID); 
GO

默认是非聚集的,但如果你想明确,你可以添加'nonclustered'关键字。

【讨论】:

  • 您好,保罗,感谢您的回复。但是,文章中提到的场景是基于 Guid 是一个 PK,而在我的例子中,Guid 不是一个 PK。我有兴趣了解更多关于 Guid 在不是 PK 时的表现。存储是一个缺点,但它与任何其他 varchar 列非常相似,只是多了一个不会有什么坏处。
  • 是的,我明白,我在回复的第一段中涵盖了这部分内容。这篇文章是为了提供更详细的背景。简而言之,在 Select 上的 guid 并不比整数差很多(只要你有一个覆盖索引),并且只有在 GUID 列是聚集索引的一部分时才会在插入时受到影响(因为 PK 通常是) .
  • 谢谢保罗。顺便说一下,什么是覆盖指数?我对 SQL 很陌生。我几乎是一个 ORM 人。
  • 没关系,我已经搜索过了。但如果你想展示它是如何实现的,那就更好了。非常感谢保罗。
  • 谢谢保罗。非常感谢您的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-17
  • 1970-01-01
  • 2023-03-29
  • 2011-07-09
  • 2017-01-24
  • 1970-01-01
相关资源
最近更新 更多