PostgreSQL生成UUID函数的性能区别
在oracle中可以使用sys_guid()函数生产UUID唯一值, 在PostgreSQL中,”uuid-ossp“扩展提供了多种方法来生成UUID值,其中包括uuid_generate_v1、uuid_generate_v3、uuid_generate_v4和uuid_generate_v5。这些方法的主要区别在于UUID的生成算法和使用的输入参数。 那它们生的效率有区别吗? 这里简单的测试。
功能 描述 |
---|
生成版本 1 UUID。这涉及计算机的 MAC 地址和时间戳。请注意,此类 UUID 会泄露创建标识符的计算机的身份以及创建标识符的时间,这可能使其不适合某些安全敏感型应用程序。 生成的UUID是基于时间的,可以用于排序和比较。 |
生成版本 1 UUID,但使用随机组播 MAC 地址,而不是计算机的实际 MAC 地址。 |
使用指定的输入名称在给定命名空间中生成版本 3 UUID。命名空间应该是表 F.33 中所示函数生成的特殊常量之一。(理论上它可以是任何UUID。该名称是所选命名空间中的标识符。 例如: SELECT uuid_generate_v3(uuid_ns_url(), 'http://www.postgresql.org'); name 参数将是 MD5 哈希的,因此明文不能从生成的 UUID 派生。通过这种方法生成的UUID没有随机或环境依赖的元素,因此是可重现的。 - 依赖于指定的命名空间和输入名称,生成的UUID是固定的。 - 可以用于在不同的命名空间中生成相同名称的UUID |
- 使用随机数生成UUID。 - 生成的UUID是完全随机的,没有特定的规律。 - 是最常用的UUID生成方法,适用于大多数情况。 |
生成版本 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
对不起,这篇文章暂时关闭评论。