PostgreSql 表中 UUID、CHAR 和 VARCHAR 之间的性能差异?

Posted

技术标签:

【中文标题】PostgreSql 表中 UUID、CHAR 和 VARCHAR 之间的性能差异?【英文标题】:Performance difference between UUID, CHAR, and VARCHAR in PostgreSql table? 【发布时间】:2015-11-18 06:42:46 【问题描述】:

我将 UUID v4 值存储在 PostgreSQL v9.4 表的“id”列下。

当我创建表时,无论我将“id”列定义为VARCHAR(36), CHAR(36),还是UUID数据类型,在写入或读取性能方面有什么不同吗?

谢谢!

【问题讨论】:

据我所知,UUID 类型使用 16 个字节,基本上将 UUID 存储为原样:一个 128 位整数。 char(36)varchar(36) 将使用 36 个字节。但是,我似乎再也找不到记录在哪里了。除此之外,如果您的 UUID 将成为您的关键并且您计划使用 CLUSTER 选项,您需要了解 PostgreSQL 如何进行表/索引集群的后果。 simononsoftware.com/how-to-store-uuids-in-postgresql 【参考方案1】:

索引大小可能是最显着的差异:VARCHAR 增加了近 86%。

从性能的角度来看,我没有注意到 PostgreSQL 9.5 的显着差异。

【讨论】:

你能用数据支持这个说法吗?具体测量、表格布局?【参考方案2】:

UUID 将是最快的,因为它的 128 位 -> 16 字节,并且比较是以数字方式完成的。

Char(36) 和 varchar(36) 似乎相同且速度慢:http://www.depesz.com/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text/。

服务器应检查 EOF 以确定读取每个字符的值的工作是否已完成。

文本比较也比数值比较慢。而且由于 UUID 由 16 个字节组成,因此比较 UUID 比比较两个 36 个字符的文本要快得多。

使用本机 UUID 提高性能。

【讨论】:

您的解释不正确。 charvarchar 这里没有显着的性能差异,至少 PostgreSQL 存储的那样。两者都在内部存储为VARLENA。此外,一个 UUID 是 16 字节(128 位);我不知道你从哪里得到“5 个十六进制值”。 好吧,我也说过它是128位和16字节。 5个十六进制值来自定义,请阅读:***.com/questions/32188497/… 关于 char 和 varchar 是一样的,是的,你是对的:depesz.com/2010/03/02/charx-vs-varcharx-vs-varchar-vs-text 我在***中查找了 UUID,5 个十六进制部分仅显示 128 位。从版本 1 到现在的版本 5,UUID 生成算法发生了变化。现在 128 位由较小的部分(mac 地址、日期、随机算法、sha-1 加密……)生成并显示为 5 个十六进制值。因此,显示为 5 个部分对计算和比较没有影响。已在答案中修复。【参考方案3】:

使用uuid。 PostgreSQL 有原生类型是有原因的。

它在内部将 uuid 存储为 128 位二进制字段。您提出的其他选项将其存储为十六进制,相比之下效率非常低。

不仅如此,而且:

uuid 对排序进行简单的按字节排序。 textcharvarchar 考虑排序规则和语言环境,这对于 uuid 来说是无意义的。

uuid 只有一种规范表示。文本等情况并非如此;您必须考虑大小写十六进制、...-...s 的存在与否等。

毫无疑问。使用uuid

唯一有意义的其他类型是bytea,它至少可以用来直接存储 uuid 的 16 个字节。如果我使用的系统无法处理基本集合之外的数据类型,例如某种非常愚蠢的 ORM,我会这样做。

【讨论】:

以上是关于PostgreSql 表中 UUID、CHAR 和 VARCHAR 之间的性能差异?的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL 统计同一张表的多列

jOOQ:比较 uuid(来自 postgresql)和字符串(类中的用户 id)

postgresql中uuid的使用

PostgreSQL 生成uuid

如何在 JPA 和自定义 UUID 标识符中实现批量插入

postgresql 中不存在函数 min(uuid)