字符串作为主键的性能损失?
Posted
技术标签:
【中文标题】字符串作为主键的性能损失?【英文标题】:performance penalty of strings as primary keys? 【发布时间】:2010-02-12 08:49:55 【问题描述】:使用字符串作为主键而不是 bigint 等会有什么性能损失?字符串比较比整数比较昂贵得多,但另一方面,我可以想象 DBMS 在内部将计算散列键以减少惩罚。
我工作的一个应用程序使用字符串作为多个表(mysql)中的主键。改变这一点并非易事,我想知道在性能方面可以获得什么来证明这项工作的合理性。
【问题讨论】:
重复? ***.com/questions/517579/… 【参考方案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 引用。
【讨论】:
以上是关于字符串作为主键的性能损失?的主要内容,如果未能解决你的问题,请参考以下文章