【问题标题】:Database Index Fragmentation: Sequential GUID saved as String works fine but not saved as GUID数据库索引碎片:保存为字符串的顺序 GUID 工作正常,但未保存为 GUID
【发布时间】:2013-10-18 07:11:19
【问题描述】:

我们使用 GUID 作为主键(我们知道这不是一个好的选择,但现在不能更改)。众所周知,我们的索引很快就会碎片化。另一个用顺序 ID 替换 GUID 的好选择。为此,代码更改如下:

旧代码:

ObjectName.Id = Guid.NewGuid();

新代码:

ObjectName.Id = Sequential.NewGuid();

这里的Sequential是我们的静态类,它使用“rpcrt4.dll”创建Sequential GUID。但是我们的测试表明,这也不适用于索引,并且它们会变得碎片化。

另一个有趣的发现是,如果我们将这个连续的 GUID 作为“字符串”保存在数据库中,那么我们的索引就不会变得碎片化。

现在我有以下疑问/疑问:

  1. 为什么当我们将相同的字符串保存为“String”和“GUID”时,服务器的行为会有所不同?根据我到目前为止的理解,它在内部将所有内容都保存为字符串。

  2. 有没有办法配置数据库来告诉我们,将我们的 GUID 视为字符串并平等对待它们?

这里是环境的一些细节:

  • 数据库:SQLExpress
  • 编码语言:C#
  • 不能依赖服务器生成密钥,我们必须从代码本身设置密钥。

即使不是精确的解决方案,也欢迎提供解决方案的指针。

【问题讨论】:

    标签: c# sql-server indexing database-fragmentation


    【解决方案1】:

    guid 不存储为字符串。它存储为 16 个字节的数据 - guid 中的字符是字节的十六进制表示,其中第一对是最低有效值。

    当 RPCRT4 生成顺序 GUID 时,它似乎将字节 4 视为最不重要的。这可能是您的索引变得碎片化的原因。

    尽管您的说法相反,我还是建议您使用 SQL Server 的 NewSequentialID 函数。

    【讨论】:

    • 感谢您对差异的解释,但问题仍然相同,我不能让 SQL Server 提供 ID。我想知道 SQL Server 本身的一些配置..
    【解决方案2】:

    顺便说一句。 - 您是否在大量计算机上生成顺序指南?由于 SQL Server 主要按源计算机特定的 guid 部分进行排序(回答此问题的详细信息 - 这可能对您有一些有价值的信息:Sequential GUIDs)。在这种情况下,您可能会通过将 Guid 转换为字节数组、交换其部分然后重新创建 Guid 来获得一些结果。

    这种方法的另一种变体可能是将 guid 的机器标识部分替换为始终相同的静态值,并使用 Guid 的不同部分(但不是时间戳特定部分!)来区分机器 - 但这只有在你' d 需要生成 guid 的机器数量非常少。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-24
      • 1970-01-01
      • 2011-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多