首页 » PostgreSQL/GaussDB » PostgreSQL生成UUID函数的性能区别

PostgreSQL生成UUID函数的性能区别

在oracle中可以使用sys_guid()函数生产UUID唯一值, 在PostgreSQL中,”uuid-ossp“扩展提供了多种方法来生成UUID值,其中包括uuid_generate_v1、uuid_generate_v3、uuid_generate_v4和uuid_generate_v5。这些方法的主要区别在于UUID的生成算法和使用的输入参数。 那它们生的效率有区别吗? 这里简单的测试。

功能

描述

uuid_generate_v1() →uuid

生成版本 1 UUID。这涉及计算机的 MAC 地址和时间戳。请注意,此类 UUID 会泄露创建标识符的计算机的身份以及创建标识符的时间,这可能使其不适合某些安全敏感型应用程序。

生成的UUID是基于时间的,可以用于排序和比较。

uuid_generate_v1mc() →uuid

生成版本 1 UUID,但使用随机组播 MAC 地址,而不是计算机的实际 MAC 地址。

uuid_generate_v3 ( 命名空间 , 名称 ) →uuidtextuuid

使用指定的输入名称在给定命名空间中生成版本 3 UUID。命名空间应该是表 F.33 中所示函数生成的特殊常量之一。(理论上它可以是任何UUID。该名称是所选命名空间中的标识符。uuid_ns_*()

例如:

SELECT uuid_generate_v3(uuid_ns_url(), 'http://www.postgresql.org');

name 参数将是 MD5 哈希的,因此明文不能从生成的 UUID 派生。通过这种方法生成的UUID没有随机或环境依赖的元素,因此是可重现的。

- 依赖于指定的命名空间和输入名称,生成的UUID是固定的。
- 可以用于在不同的命名空间中生成相同名称的UUID

uuid_generate_v4() →uuid

- 使用随机数生成UUID。
- 生成的UUID是完全随机的,没有特定的规律。
- 是最常用的UUID生成方法,适用于大多数情况。

uuid_generate_v5 ( 命名空间 , 名称 ) →uuidtextuuid

生成版本 5 UUID,其工作方式与版本 3 UUID 类似,只是 SHA-1 用作哈希方法。版本 5 应优先于版本 3,因为 SHA-1 被认为比 MD5 更安全。 依赖于指定的命名空间和输入名称,生成的UUID是固定的。 – 可以用于在不同的命名空间中生成相同名称的UUID。

同时还有gen_random_uuid()也可以生成V4版本的随机UUID, 官方宣称它是最常用的,选择哪种方法取决于具体的需求和使用场景。通常情况下,使用uuid_generate_v4方法生成的UUID已经足够满足大多数需要唯一标识符的场景。当大批量生成数据时,他们的效率哪个更高呢?以下测试使用“墨天轮”网站的的SQL工作台工具, postgresql V15版本, 注您的硬件不通可能结果不同,但不影响我们的顺序。

需要注意的是,使用”uuid-ossp”扩展需要先安装并启用扩展。可以使用以下命令来安装和启用扩展:

首先创建uuid-ossp插件

select version();
-----------------------------
PostgreSQL 15.0 (Debian 15.0-1.pgdg110+1) on aarch64-unknown-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

UUID_GENERATE_V1

EXPLAIN(COSTS OFF,ANALYZE )SELECT UUID_GENERATE_V1() FROM GENERATE_SERIES(1,1E6)N;

Function Scan on generate_series n (actual time=263.338..7592.035 rows=1000000 loops=1)
Planning Time: 0.040 ms
Execution Time: 7662.258 ms

Note:
V1 有根据真实的MAC和时间戳,生成的信息可能会泄露服务器信息。

UUID_GENERATE_V3

SELECT UUID_GENERATE_V3(uuid_ns_oid(),'anbob.com') FROM GENERATE_SERIES(1,1E6)N;

dfc9ea7d-486e-37a7-898d-5a065d19078e
dfc9ea7d-486e-37a7-898d-5a065d19078e
dfc9ea7d-486e-37a7-898d-5a065d19078e
dfc9ea7d-486e-37a7-898d-5a065d19078e
...

create sequence s cache 1000;

EXPLAIN(COSTS OFF,ANALYZE )SELECT UUID_GENERATE_V3(uuid_ns_oid(),nextval('s')::text) FROM GENERATE_SERIES(1,1E6)N;

Function Scan on generate_series n (actual time=263.842..1961.929 rows=1000000 loops=1)
Planning Time: 0.062 ms
Execution Time: 2013.784 ms

Note:
v3函数的NAME 可以固定值,生成的uuid相同, 理论上可以复现值。这里借助sequence生成唯一值。

UUID_GENERATE_V4

EXPLAIN(COSTS OFF,ANALYZE )SELECT UUID_GENERATE_V4() FROM GENERATE_SERIES(1,1E6)N;

Function Scan on generate_series n (actual time=269.975..6173.335 rows=1000000 loops=1)
Planning Time: 0.041 ms
Execution Time: 6226.739 m

GEN_RANDOM_UUID

EXPLAIN(COSTS OFF,ANALYZE )SELECT GEN_RANDOM_UUID() FROM GENERATE_SERIES(1,1E6)N;

Function Scan on generate_series n (actual time=263.666..2991.858 rows=1000000 loops=1)
Planning Time: 0.052 ms
Execution Time: 3045.946 ms

UUID_GENERATE_V5

EXPLAIN(COSTS OFF,ANALYZE )SELECT UUID_GENERATE_V5(uuid_ns_oid(),nextval('s')::text) FROM GENERATE_SERIES(1,1E6)N;

Function Scan on generate_series n (actual time=265.207..1852.115 rows=1000000 loops=1)
Planning Time: 0.048 ms
Execution Time: 1902.541 ms

总结:
选择哪种方法取决于具体的需求和使用场景。通过批量生成数据的响应时间维度,对比不同的函数后,发现使用UUID_GENERATE_V5生成的效率最高,如果仅从生成唯一值需求,生成的效率UUID_GENERATE_V5  >  UUID_GENERATE_V3(sequence)  > GEN_RANDOM_UUID > UUID_GENERATE_V4 >UUID_GENERATE_V1

打赏

对不起,这篇文章暂时关闭评论。