【问题标题】:performance penalty of strings as primary keys?字符串作为主键的性能损失?
【发布时间】:2010-02-12 08:49:55
【问题描述】:

使用字符串作为主键而不是 bigint 等会有什么性能损失?字符串比较比整数比较昂贵得多,但另一方面,我可以想象 DBMS 在内部将计算散列键以减少惩罚。

我工作的一个应用程序使用字符串作为多个表(MySQL)中的主键。改变这一点并非易事,我想知道在性能方面可以获得什么来证明这项工作的合理性。

【问题讨论】:

标签: mysql database primary-key


【解决方案1】:

另一方面,我可以想象 DBMS 将在内部计算哈希 减少惩罚的关键。

数据库需要维护一个 B-Tree(或类似的结构),其中包含键,以便对它们进行排序。

如果密钥经过哈希处理并将其存储在 B-Tree 中,可以快速检查密钥的唯一性——仍然可以有效地查找密钥。但是您将无法有效地搜索 range 数据(例如使用 LIKE),因为 B-Tree 不再根据字符串值排序。

所以我认为大多数数据库确实将字符串存储在 B-Tree 中,这可能 (1) 占用比数值更多的 空间 并且 (2) 要求 B-Tree 是 如果以任意顺序插入键,则重新平衡(没有像数字 pk 那样增加值的概念)。

实践中的惩罚可以从微不足道到巨大。这完全取决于使用情况、行数、字符串键的平均大小、连接表的查询等。

【讨论】:

    【解决方案2】:

    在我们的产品中,我们使用 varchar(32) 作为主键 (GUID),我们还没有遇到过这样的性能问题。我们的产品是一个极度过载的网站,对于稳定至关重要。 我们使用 SQL Server 2005。

    编辑:在我们最大的表中,我们有超过 3 000 000 条记录,其中包含大量插入和选择。我认为总的来说,迁移到 int key 的好处会非常低,但是迁移时的问题非常高。

    【讨论】:

    • SQL Server 中有一个 GUID 类型。此外,它非常适合复制。
    【解决方案3】:

    需要注意的一件事是页面拆分(我知道这可能发生在 SQL Server 中 - 在 MySQL 中可能相同)。

    主键是物理排序的。通过使用自动增量整数,您可以保证每次插入时都会向上插入下一个数字,因此数据库不需要重新排序键。但是,如果您使用字符串,您插入的 pk 可能需要放在其他键的中间以保持 pk 顺序。在插入件上重新排序 pk 的过程可能会很昂贵。

    【讨论】:

      【解决方案4】:

      这取决于几个因素:RDBMS、涉及这些列的索引数量,但通常使用 int 会更有效,其次是 bigint。

      任何性能提升都取决于使用情况,因此如果没有表架构和查询工作负载的具体示例,很难说。

      除非它在域中有意义(我在想像社会安全号码这样独特的东西),否则代理整数键是一个不错的选择;当被引用对象发生变化时,引用对象不需要更新其 FK 引用。

      【讨论】:

        猜你喜欢
        • 2011-05-04
        • 2015-03-27
        • 2020-03-16
        • 2015-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多