从 MySQL 这边看 PostgreSQL 18
PostgreSQL 18 的正式发布日是 2025 年 9 月 25 日。我按 MySQL 这边的习惯读了一遍它的发布说明,有几条是真正值得停一下的,其余是常规演进。这篇就挑值得停下来的那几条说。
一、uuidv7():这条最实用
PG 18 内置了 uuidv7(),生成时间有序的 UUID。
要理解为什么这值得单独一条,得先看 UUID 主键的经典代价:v4 完全随机,写入位置在 B+ 树上是均匀散布的,每一行插入都是一次随机写,页分裂不断发生,索引膨胀明显,缓存命中率差。用 UUID 做主键的系统,多数要靠「按时间有序的自定义 ID」来绕开,比如 Snowflake 那一类。
uuidv7() 走的是另一条路:保留 UUID 的 128 位格式和跨系统唯一性,但把时间戳放在高位,于是单调递增、写入集中在最右侧的页。等于把「有序 ID 的写入友好」和「UUID 的无需协调」这两件事同时拿到。
对 MySQL 用户,这条的实际含义有两层:
- 如果你在 MySQL 上一直被 UUID 主键的膨胀困扰(
UUID()也是随机的,问题一模一样),那 PG 现在提供了一个不需要应用层参与的答案。这是选型比较时会被人拿出来的加分项。 - 更值得抄的是思路而不是函数:主键生成该按时间有序来设计。MySQL 侧对应的做法是自己生成有序 ID(把时间戳放高位的 BIGINT,或者有序填充的变体),别指望数据库给一个
uuidv7()。
二、异步 I/O:那个「3 倍」要自己复测
PG 18 换了新的异步 I/O 子系统,由 io_method 这一项在几种实现之间选(维持原来的同步方式、worker、以及 io_uring),官方说明受益的是顺序扫描、位图扫描和 VACUUM 这类场景,给出的数字是最高 3 倍。
这里必须把「最高」这两个字读实:那是官方在选定的最佳情形下的结果,不是一句基准平均。落到具体系统上的收益取决于你的负载里顺序扫和 VACUUM 占多少——OLTP 点查为主的库,几乎拿不到;大表扫描、报表、以及 VACUUM 压力重的库,可能很明显。
我的建议是不看这个数字,自己量:拿一台预发机器、一份还原出来的生产数据、跑你真实的最重的那几条查询,对比 io_method 几种取值。这件事的成本是一天,而它决定的是要不要为升级专门排一次容量评估。
顺带一提,io_uring 这条路对 Linux 内核版本有要求,且它在容器环境里的可用性不是理所当然的——不少托管环境和安全策略会限制它。这也是要提前验的一项,别到时候发现只能用 worker。
三、虚拟生成列:向 MySQL 的语义对齐
PG 18 的生成列默认是**虚拟(VIRTUAL)**的,也就是查询时计算、不占存储。这正好和 MySQL 的默认行为一致——MySQL 的 GENERATED ALWAYS AS ... VIRTUAL 同样是读时算,STORED 才落盘。
以前 PG 只有 STORED,这是很多「从 MySQL 迁到 PG」的项目会撞上的一个差异点:迁移工具遇到生成列只能改成存储生成,然后表的实际大小和写入放大就对不上了。现在这个差异抹平了。
不过两者的读放大代价是一样的:虚拟列每次查询都要重算,所以在大结果集上过滤这一列,MySQL 和 PG 都不划算。要索引它,就得落成存储生成。这一条判断两边通用。
四、协议 3.2:这条最容易被忽略
PG 18 把通信协议升到了 3.2,同时 libpq 默认仍回落到 3.0 以保持兼容——协议这一层能动默认值,本身就说明它不是一次小修。
对应用侧的意义在于:兼容性风险不在数据库,在中间层。连接池、代理(PgBouncer 这类)、以及各家语言驱动的更新节奏,通常都比数据库慢。跨版本升级时最容易出的事故形式是「库升完了,某个中间件不认新握手」,而这一步往往不在升级演练的范围内。
所以真正该做的检查是:把链路上所有会解析协议的组件(驱动、连接池、代理、监控采集)列个清单,逐个确认它们声明支持的协议范围。协议版本号这件事,平时看不见,出事时是唯一原因。
五、两条给运维的实用项
pg_upgrade支持并行跑,新增的具体开关以官方那一页为准。 值得单独说的是统计信息这一项:以前大版本升级后统计信息清空,优化器在冷启动状态下选计划,最典型的表现就是升级当晚一堆查询集体变慢,得等 ANALYZE 跑完才恢复。新版本在这一点上的改进方向是「升级后不要把统计全丢掉」,具体到哪一个命令行参数做到、以及和你手上版本的兼容性,动手前查pg_upgrade那一页的选项列表,别照抄别人文章里的示例命令。initdb默认开启页校验和(page checksums)。 数据页损坏能被发现,而不是等到读出来才发现是乱码。这是那种「早该默认开」的改动。
我的结论
PG 18 不是一个大版本级别的震撼发布,但它的取向很明确:把运维层面长期欠账的默认值补上(校验和、统计信息保留、协议回退兼容),同时在 ID 生成这类具体工程痛点上给出内置答案。
对我这种日常写 MySQL 的人,实际收获有两条。一条是可以直接抄的做法:主键按时间有序生成。另一条是下次做存储选型对比时,UUID 主键这一项不再是 PG 的减分项了——过去它是。
本文作者:Aryee 发布时间:2026-09-24 20:28
本文出处:ARYEE.cn 固定链接:https://www.aryee.cn/archives/postgres-18-for-mysql-people.html
转载或引用请连这一行一起带走;文中的代码与结论按当时环境成立,组件升级后请以官方文档为准。