对 UUID 主键使用字符串类型与 uuid 类型相比,对性能有何影响?

What is the performance hit of using a string type vs a uuid type for a UUID primary key?

对于主键使用 string 与实际的 uuid 类型相比,索引查找的速度是否有很大差异,特别是如果字符串具有像 user-94a942de-05d3-481c-9e0c-da319eb69206 这样的前缀(使查找必须遍历 5-6 个字符才能找到唯一的东西)?

这是一个微观优化,在达到巨大规模之前不太可能导致真正的性能问题。使用最适合您的设计的密钥。也就是说,这是详细信息...

UUID is a built in PostgreSQL type。它基本上是一个 128 位整数。它应该像任何其他大整数一样作为索引执行。 Postgres 没有内置的 UUID 生成函数。可以安装各种模块在数据库上做,也可以在客户端做。在客户端生成 UUID 将额外的工作(不多的额外工作)从服务器分发出去。

MySQL 没有内置的 UUID 类型。相反,有一个 UUID function 可以将 UUID 生成为一串十六进制数字。因为它是一个字符串,UUID 键可能会影响性能和存储。它还可能会干扰复制。

字符串UUID会更长;十六进制字符每个字节仅编码 4 位数据,因此十六进制字符串 UUID 需要 256 位来存储 128 位信息。这意味着每列有更多的存储空间和内存,这会影响性能。

通常这意味着比较的时间是原来的两倍,因为被比较的键是原来的两倍。但是,UUID 通常在前几个字节中是唯一的,因此不需要比较整个 UUID 就知道它们是不同的。长话短说:比较字符串和二进制 UUID 不会在实际应用程序中造成明显的性能差异......尽管 MySQL UUID 是 UTF8 编码的事实可能会增加成本。

在 PostgreSQL 上使用 UUID 没问题,它是内置类型。 MySQL 对 UUID 密钥的实现非常不完整,我会避开它。远离 MySQL 的时候。

当 table(或至少索引)太大而无法缓存在 RAM 中时,UUID 就会出现真正的问题。发生这种情况时,需要将 'next' uuid 存储到(或从中获取)一些 random 块,该块 unlikely 被缓存.随着 table 的增长,这会导致越来越多的 I/O。

AUTO_INCREMENT ids 通常 不会受到 I/O 增长的影响,因为 INSERTs 总是在 'end' table 和 SELECTs 通常 聚集在最后。这导致缓存的有效使用,从而避免了死于 IO。

我的 UUID blog 讨论了如何降低 "Type-1" UUID 的性能成本,至少对于 MySQL。