【问题标题】:Searching table by Guid faster when the Guid is the clustered index?当 Guid 是聚集索引时,通过 Guid 搜索表更快?
【发布时间】:2011-03-07 08:38:37
【问题描述】:

如果我要通过 Guids 查询表(不管 Guids 的碎片问题),将 Guid 作为聚集索引而不是非聚集索引或根本没有索引会更快吗?

这个问题来自只读的角度。我只是好奇特定 Guid 的搜索行之间的速度是否会有所提高,并且在有/没有索引或有/没有聚集索引的情况下会更快地完成搜索吗?

或者,我对下一个问题的答案相当肯定,但现在将 int 标识符应用于上一个问题。如果该表由该 int 聚集,搜索会更快吗? (这是不是被表中的其他项目聚集在一起?)




我知道关于这个主题还有很多其他问题,但我没有在这些问题中找到我正在寻找的具体答案:
Should a Sequential Guid primary key column be a clustered index?
Improving performance of cluster index GUID primary key
Clustered primary key on unique identifier ID column in SQL Server
uniqueidentifier with index
Should I get rid of clustered indexes on Guid columns

感谢您的帮助!

【问题讨论】:

  • 比什么更快?我认为替代方案是非聚集覆盖索引?
  • 太棒了!我会像魔鬼一样避免将 GUID 作为 SQL Server 中的聚集索引!不要这样做——即使这样搜索 GUID 更快——大多数其他操作都会以 GUID 作为 CK....
  • @Martin Smith - 我的意思是光栅比非聚集索引或根本没有索引@marc_s - 如果我专门讨论的话,我们谈论的其他操作将会变得爬行从表中读取?

标签: sql guid clustered-index


【解决方案1】:

使用整数聚集索引查询表肯定会比 GUID 索引更快。原因是数据类型的大小。

如果您已经决定使用 GUID 作为键,那么可能会使用 newSequentialId() 而不是 NewId() 生成这些 GUID,因为这将减少 Guid 索引中碎片的影响,因为 Ids ae 总是在增加并且您的机会更少有一个页面拆分。

补充一点,除非您有潜在的聚集索引候选者,即如果您将此 guid 用于非关键目的,否则将其用作聚集索引是一个自然的选择。如果它是一个相对较小的表,那么当您可以选择不使用索引时,拥有索引总是好的。

【讨论】:

    【解决方案2】:

    假设 MS SQL Server。这可能适用于也可能不适用于其他 RDBMS:

    如果您有聚集索引,那么它将是最快的,但如果您正在搜索单行,那么它与非聚集索引之间的差异可以忽略不计。当您使用非聚集索引时,服务器需要首先在索引中找到正确的值,然后从表存储中获取完整记录。表存储是聚集索引,因此通过聚集索引进行搜索消除了该步骤(称为书签查找),但该步骤对于单行几乎是察觉不到的。

    当聚集索引位于按范围选择的列上时(例如,交易日期并且您想要查找过去一个月的所有交易),它们往往会为读取提供更大的优势。在这种情况下,服务器可以找到起点,并在一次快速、连续的扫描中读取数据。

    在 INT 上使用非聚集索引(所有其他条件相同)将比使用 GUID 稍快,因为索引本身会更小(因为 INT 比 GUID 小得多),这意味着服务器必须遍历更少的页面以找到它想要获得的值。在聚集索引的情况下,如果您的行大小与 GUID 和 INT 之间的差异相比已经很大,我认为您不会看到太大的差异,但我没有对此进行任何测试。

    【讨论】:

      【解决方案3】:

      就像 Tom 已经提到的,在聚集索引上搜索单个元素总是会更快。这是因为聚集索引本身就是数据,找到索引条目后不需要查找。

      聚集索引的主要优点是能够提取“范围”数据(如“上周”或“按日期排列的订单历史”)。由于 GUID 倾向于均匀地分布在整个表中,因此您将无法在此处获得此好处。另外每张表只能有一个聚集索引,请谨慎选择。

      如果您最常查询特定范围的表,则将该表视为聚集索引。

      还有第三种,称为覆盖索引。覆盖索引由几个字段组成,它们将能够满足最常见的查询。例如,您有一个带有 ID、Displayname、Password、LogonDate 的 USER 表,您将经常需要 DisplayName,根据 ID 创建索引,Displayname 将被视为查询的覆盖索引,例如

      Select Displayname from USER where ID=XYZ

      编辑: 一件事我忘了提。就 SQL 而言,GUID 是一个相当大的对象(嗯... 16 字节)。将其作为聚集索引会强制该表上的所有其他索引包含指向 GUID 的 16 字节指针。如果您在该表上有一堆索引,这可以加起来。聚集索引最好是小而独特。这就是 INT 如此出色的原因。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-08-04
        • 2010-12-17
        • 2015-03-12
        • 2014-07-28
        • 1970-01-01
        • 2014-07-30
        • 2010-09-21
        相关资源
        最近更新 更多