提问者:小点点

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


使用字符串作为主键与实际 uuid 类型进行索引查找的速度差异是否很大,特别是如果字符串具有类似 user-94a942de-05d3-481c-9e0c-da319eb69206 的前缀(使查找必须遍历 5-6 个字符才能获得唯一内容)?


共3个答案

匿名用户

这是一种微观优化,在达到巨大规模之前,不太可能导致真正的性能问题。使用最适合您设计的钥匙。也就是说,下面是细节。。。

UUID是内置的PostgreSQL类型。它基本上是一个128位整数。它应该像任何其他大整数一样作为索引执行。Postgres没有内置的UUID生成函数。您可以在数据库上安装各种模块来完成这项工作,也可以在客户机上完成这项工作。在客户机上生成UUID会将额外的工作(没有太多额外的工作)从服务器上分配出去。

MySQL没有内置的UUID类型。取而代之的是,有一个UUID函数可以生成一串十六进制数字的UUID。因为它是一个字符串,所以 UUID 密钥可能会对性能和存储产生影响。它还可能干扰复制。

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

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

在PostgreSQL上使用UUID很好,它是一种内置类型。MySQL对UUID键的实现非常不完整,我会避开它。当你在使用MySQL时,避开它。

匿名用户

UUID的真正问题在于表(或至少索引)太大而无法缓存在RAM中。发生这种情况时,“下一个”uuid需要存储到(或从)一些不太可能被缓存的随机块中。随着表的增长,这会导致越来越多的I/O。

AUTO_INCREMENTid通常不会受到I/O增长的影响,因为INSERTs总是在表的“末尾”,而SELECTsSELECT通常在末尾附近聚集。这导致了缓存的有效使用,从而避免了IO的死亡。

我的UUID博客讨论了如何使“Type-1”UUID的性能成本更低,至少对于MySQL而言。

匿名用户

使用映射到128位整数的内置UUID类型。不仅仅是为了提高性能,也是为了防止类似“password1”的字符串出现在该列中。