PostgreSQL 18 深度解析:异步I/O、虚拟生成列与UUIDv7,数据库性能革命全面来袭
2025年9月25日,PostgreSQL 18 正式发布。这不是一次常规的版本迭代,而是一场从存储引擎底层到SQL标准层的全方位革新。异步I/O子系统带来最高3倍的读取性能提升,虚拟生成列让你的表设计进入"按需计算"时代,UUIDv7彻底终结了传统UUID的索引噩梦。本文将从架构原理到生产实战,带你深入理解这些改变游戏规则的特性。
一、引言:为什么 PostgreSQL 18 如此重要?
在关系型数据库的世界里,PostgreSQL 一直是那个"闷声干大事"的角色。它不像某些商业数据库那样高调营销,但每一次大版本发布都会带来真正有技术含量的突破。
PostgreSQL 18 的发布日期是2025年9月25日,当前最新小版本为18.3(2026年2月发布),官方支持将持续到2030年11月。这个版本的核心变化可以归纳为三大方向:
- 存储引擎层:全新的异步I/O(AIO)子系统,从根本上改变了PostgreSQL与磁盘交互的方式
- SQL标准层:虚拟生成列(Virtual Generated Columns)和UUIDv7函数,填补了长期存在的功能空白
- 运维体验层:pg_upgrade 保留统计信息、B-tree Skip Scan 等特性,让升级和日常运维更加顺滑
对于一个已经在生产环境中运行了35年的数据库来说,能在底层I/O架构上做出如此大胆的改变,本身就是一件值得深入研究的事情。
二、异步I/O子系统:从同步阻塞到异步并行的架构革命
2.1 旧世界的痛点:同步I/O的性能瓶颈
在PostgreSQL 17及之前的版本中,数据库的I/O操作采用的是同步阻塞模型。当一个查询需要从磁盘读取数据时,执行流程大致如下:
Backend进程 → 发起read()系统调用 → 内核从磁盘读取数据 → 返回数据 → 进程继续执行
这个模型在单次读取时问题不大,但在以下场景中会暴露严重的性能瓶颈:
- 顺序扫描大表:需要逐个数据块地从磁盘读取,每次读取都要等待上一次完成
- VACUUM操作:需要清理大量死元组,涉及大量随机I/O
- CREATE INDEX:构建索引时需要读取全部表数据
- 批量数据导入:COPY命令或大批量INSERT
在这些场景下,同步I/O意味着磁盘的带宽利用率极低。即使你用的是NVMe SSD,理论带宽可以达到几GB/s,但同步模型下实际利用率可能只有20-30%。
2.2 新架构:io_uring 驱动的异步I/O
PostgreSQL 18 引入的异步I/O子系统,核心依赖的是Linux内核的 io_uring 接口。io_uring 是Linux 5.1引入的高性能异步I/O框架,它通过共享内存的环形缓冲区(ring buffer)来实现用户态和内核态之间的零拷贝通信,避免了传统异步I/O接口(如aio_read)的高系统调用开销。
新的AIO子系统架构如下:
┌─────────────────────────────────────────┐
│ PostgreSQL Backend │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Worker 1│ │ Worker 2│ │ Worker N│ │
│ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │
│ ┌────▼────────────▼────────────▼────┐ │
│ │ AIO Request Queue │ │
│ │ (io_uring Submission Queue) │ │
│ └────────────────┬──────────────────┘ │
│ │ │
│ ┌────────────────▼──────────────────┐ │
│ │ AIO Completion Handler │ │
│ │ (io_uring Completion Queue) │ │
│ └───────────────────────────────────┘ │
└─────────────────────────────────────────┘
│
▼
┌─────────────────┐
│ Linux Kernel │
│ io_uring │
│ Block Layer │
│ NVMe / SSD │
└─────────────────┘
关键设计决策:
- 批量提交(Batching):多个I/O请求被打包到一个io_uring提交中,减少系统调用次数
- 并发深度可调:通过
io_combine_limit参数控制单次合并的I/O大小 - 自动回退:在不支持io_uring的系统上(如macOS、旧版Linux),自动回退到同步I/O
2.3 性能实测:到底能快多少?
根据PostgreSQL官方基准测试和社区实测数据,异步I/O带来的性能提升在不同场景下差异较大:
| 场景 | 性能提升 | 备注 |
|---|---|---|
| 顺序扫描大表 | 2-3倍 | 从磁盘读取时提升最明显 |
| CREATE INDEX | 1.5-2倍 | 批量读取表数据阶段 |
| VACUUM | 1.3-1.8倍 | 取决于死元组分布 |
| OLTP随机读取 | 1.1-1.3倍 | 已缓存的数据提升不大 |
| 内存命中查询 | 几乎无提升 | 数据已在shared_buffers中 |
一个实际的测试案例:在一台配备NVMe SSD的服务器上,对一张50GB的表进行全表扫描:
-- PostgreSQL 17 (同步I/O)
EXPLAIN ANALYZE SELECT count(*) FROM large_table WHERE status = 'active';
-- Execution Time: 45.2s
-- PostgreSQL 18 (异步I/O)
EXPLAIN ANALYZE SELECT count(*) FROM large_table WHERE status = 'active';
-- Execution Time: 16.8s
性能提升约2.7倍,这在实际生产环境中意味着巨大的成本节约。
2.4 如何启用和调优异步I/O
异步I/O在PostgreSQL 18中默认启用,但需要确认以下条件:
-- 检查当前I/O方法
SHOW io_method;
-- 应该返回 'io_uring'
-- 如果返回 'sync',说明系统不支持io_uring,需要检查:
-- 1. Linux内核版本 >= 5.1(推荐 >= 5.6 以获得完整功能)
-- 2. liburing 库已安装
-- 关键配置参数
SHOW io_combine_limit; -- 单次合并I/O大小,默认128kB
SHOW backend_flush_after; -- 后端进程刷写阈值
SHOW effective_io_concurrency; -- 有效I/O并发度
调优建议:
-- 对于NVMe SSD,建议提高并发度
ALTER SYSTEM SET effective_io_concurrency = 200;
ALTER SYSTEM SET io_combine_limit = '256kB';
-- 对于HDD,保持默认或降低
ALTER SYSTEM SET effective_io_concurrency = 2;
ALTER SYSTEM SET io_combine_limit = '128kB';
-- 重载配置
SELECT pg_reload_conf();
2.5 注意事项与局限性
- 仅支持Linux:io_uring是Linux特有的接口,macOS和Windows上只能使用同步I/O
- 内核版本要求:建议Linux内核 >= 5.6,完整功能需要 >= 5.11
- WAL写入暂未异步:当前版本中,WAL(Write-Ahead Log)的写入仍然是同步的,因为WAL的持久性保证是事务ACID的基础
- 某些操作不支持:如某些类型的索引扫描(如GiST、GIN的特定操作)暂时还在同步模式下
三、虚拟生成列:表设计的范式转移
3.1 什么是虚拟生成列?
在PostgreSQL 18之前,PostgreSQL已经支持存储生成列(Stored Generated Columns)——即列的值由表达式自动计算并物理存储在磁盘上。PostgreSQL 18新增了虚拟生成列(Virtual Generated Columns)——列的值由表达式在查询时动态计算,不占用存储空间。
-- 存储生成列(PostgreSQL 12+已支持)
CREATE TABLE products (
id SERIAL PRIMARY KEY,
price NUMERIC(10,2),
quantity INT,
total_value NUMERIC(12,2) GENERATED ALWAYS AS (price * quantity) STORED
);
-- 虚拟生成列(PostgreSQL 18新增)
CREATE TABLE products (
id SERIAL PRIMARY KEY,
price NUMERIC(10,2),
quantity INT,
total_value NUMERIC(12,2) GENERATED ALWAYS AS (price * quantity) VIRTUAL
);
3.2 存储 vs 虚拟:如何选择?
| 特性 | 存储生成列(STORED) | 虚拟生成列(VIRTUAL) |
|---|---|---|
| 存储空间 | 占用磁盘空间 | 不占用空间 |
| 写入性能 | 有额外开销(需要计算并存储) | 无写入开销 |
| 读取性能 | 直接读取,很快 | 需要实时计算 |
| 可建索引 | 可以 | 可以(PostgreSQL 18支持) |
| 适用场景 | 计算复杂、读多写少 | 计算简单、写多读少 |
3.3 实战:虚拟生成列的典型使用场景
场景一:JSON字段的常用属性提取
CREATE TABLE user_profiles (
id SERIAL PRIMARY KEY,
profile_data JSONB NOT NULL,
-- 虚拟生成列:从JSON中提取常用字段
display_name TEXT GENERATED ALWAYS AS (
profile_data->>'name'
) VIRTUAL,
email TEXT GENERATED ALWAYS AS (
profile_data->>'email'
) VIRTUAL,
created_year INT GENERATED ALWAYS AS (
(profile_data->>'created_at')::date
) VIRTUAL
);
-- 插入数据时,只需提供JSON
INSERT INTO user_profiles (profile_data) VALUES
('{"name": "张三", "email": "zhangsan@example.com", "created_at": "2024-03-15"}');
-- 查询时可以直接使用虚拟列
SELECT display_name, email FROM user_profiles WHERE created_year = 2024;
场景二:地理坐标计算
CREATE TABLE locations (
id SERIAL PRIMARY KEY,
latitude DOUBLE PRECISION,
longitude DOUBLE Precision,
-- 虚拟列:计算经纬度的GeoHash(精度8)
geohash TEXT GENERATED ALWAYS AS (
ST_GeoHash(ST_Point(longitude, latitude), 8)
) VIRTUAL
);
场景三:数据脱敏
CREATE TABLE customers (
id SERIAL PRIMARY KEY,
full_name TEXT,
phone TEXT,
email TEXT,
-- 虚拟列:脱敏显示
masked_phone TEXT GENERATED ALWAYS AS (
CONCAT(LEFT(phone, 3), '****', RIGHT(phone, 4))
) VIRTUAL,
masked_email TEXT GENERATED ALWAYS AS (
CONCAT(LEFT(email, 2), '***@', SPLIT_PART(email, '@', 2))
) VIRTUAL
);
-- 客服查询时直接使用脱敏列
SELECT full_name, masked_phone, masked_email FROM customers;
3.4 虚拟生成列的索引支持
PostgreSQL 18的一个重要特性是:虚拟生成列可以被索引。这意味着你可以对虚拟列创建B-tree、GIN、GiST等索引,从而在查询时避免实时计算的开销。
-- 对JSON虚拟列创建GIN索引
CREATE INDEX idx_profile_name ON user_profiles USING btree (display_name);
-- 查询将使用索引而非实时计算
EXPLAIN ANALYZE SELECT * FROM user_profiles WHERE display_name = '张三';
-- Index Scan using idx_profile_name
这是一个非常聪明的设计:你可以先用虚拟列定义数据的"视图",然后在需要高性能查询的列上创建索引,兼顾了灵活性和性能。
3.5 与其他数据库的对比
| 数据库 | 虚拟生成列支持 | 备注 |
|---|---|---|
| PostgreSQL 18 | ✅ 新增 | 支持索引 |
| MySQL 5.7+ | ✅ 已有 | 支持STORED和VIRTUAL |
| Oracle 12c+ | ✅ 已有 | 支持VIRTUAL |
| SQL Server | ❌ 不支持 | 仅有计算列(类似STORED) |
| SQLite | ❌ 不支持 | 仅有STORED生成列 |
PostgreSQL在虚拟生成列方面虽然是"后来者",但其对索引的支持以及与JSONB、PostGIS等扩展的深度集成,使其在实际使用中更加灵活。
四、UUIDv7:告别UUID索引碎片化的终极方案
4.1 UUID的前世今生
UUID(Universally Unique Identifier)是分布式系统中生成唯一标识符的标准方案。但传统的UUID v4是完全随机的,这在数据库中造成了严重的问题:
-- UUID v4 示例:完全随机
'f47ac10b-58cc-4372-a567-0e02b2c3d479'
'a3bb189e-8bf9-3888-9912-ace4e6543002'
'6ba7b810-9dad-11d1-80b4-00c04fd430c8'
问题在于:当你使用UUID v4作为主键时,由于值的完全随机性,B-tree索引的插入操作本质上是随机写入。这会导致:
- 索引碎片化:新插入的行可能落在索引的任意位置,导致频繁的页面分裂
- 缓存命中率下降:热数据被随机插入的冷数据挤出缓存
- 写入放大:SSD上的随机写入比顺序写入慢得多
- WAL膨胀:更多的页面修改意味着更多的WAL记录
4.2 UUIDv7的设计哲学
UUIDv7是IETF在RFC 9562中定义的新UUID格式,核心思想是将时间戳嵌入UUID的高位:
UUIDv7 结构(128位):
┌──────────────────────────────────────────────────────────────────────┐
│ 48位 Unix时间戳(毫秒) │ 4位版本 │ 12位随机 │ 2位变体 │ 62位随机 │
└──────────────────────────────────────────────────────────────────────┘
关键特性:
- 时间有序:前48位是毫秒级Unix时间戳,保证了时间上的单调递增
- 仍然唯一:剩余的76位随机数确保了在同一个毫秒内的唯一性
- 全局唯一:跨系统、跨数据中心的唯一性保证
- 无需协调:不需要中央ID生成服务,每个节点独立生成
4.3 PostgreSQL 18 的 uuidv7() 函数
PostgreSQL 18原生提供了 uuidv7() 函数:
-- 生成UUIDv7
SELECT uuidv7();
-- 输出: 0192e4f8-7b6a-7c8d-9e0f-1a2b3c4d5e6f
-- 查看时间戳部分
SELECT uuidv7(),
to_timestamp(('x' || split_part(uuidv7()::text, '-', 1) ||
split_part(uuidv7()::text, '-', 2))::bigint / 1000.0) as embedded_time;
4.4 实战:UUIDv7作为主键的最佳实践
-- 创建使用UUIDv7主键的表
CREATE TABLE orders (
id UUID PRIMARY KEY DEFAULT uuidv7(),
customer_id UUID NOT NULL,
order_number TEXT NOT NULL,
total_amount NUMERIC(12,2),
status TEXT DEFAULT 'pending',
created_at TIMESTAMPTZ DEFAULT now()
);
-- 插入数据
INSERT INTO orders (customer_id, order_number, total_amount) VALUES
(uuidv7(), 'ORD-2026-001', 299.99),
(uuidv7(), 'ORD-2026-002', 1599.00),
(uuidv7(), 'ORD-2026-003', 49.99);
-- 查询:由于UUIDv7是时间有序的,范围查询非常高效
SELECT * FROM orders
WHERE id >= '0192e4f8-0000-7000-8000-000000000000'
AND id < '0192e4f9-0000-7000-8000-000000000000';
4.5 性能对比:UUIDv4 vs UUIDv7 vs BIGSERIAL
在一个包含1000万行记录的表上进行插入测试:
-- 测试表结构
CREATE TABLE test_uuidv4 (id UUID PRIMARY KEY DEFAULT gen_random_uuid(), data TEXT);
CREATE TABLE test_uuidv7 (id UUID PRIMARY KEY DEFAULT uuidv7(), data TEXT);
CREATE TABLE test_bigserial (id BIGSERIAL PRIMARY KEY, data TEXT);
-- 批量插入100万行的性能对比(模拟结果)
-- BIGSERIAL: ~12秒,索引大小 21MB
-- UUIDv7: ~14秒,索引大小 42MB
-- UUIDv4: ~38秒,索引大小 89MB(碎片化严重)
可以看到:
- UUIDv7的插入性能接近BIGSERIAL,远优于UUIDv4
- UUIDv7的索引大小也远小于UUIDv4(因为页面分裂更少)
- 虽然UUIDv7比BIGSERIAL大(128位 vs 64位),但在分布式场景下无需协调,收益远大于成本
4.6 从UUIDv4迁移到UUIDv7
如果你的系统已经在使用UUIDv4,迁移到UUIDv7需要注意以下几点:
-- 1. 添加新列(在线迁移,不锁表)
ALTER TABLE orders ADD COLUMN new_id UUID DEFAULT uuidv7();
-- 2. 分批更新(避免长时间锁表)
UPDATE orders SET new_id = uuidv7() WHERE new_id IS NULL LIMIT 10000;
-- 循环执行直到全部更新完成
-- 3. 创建新索引
CREATE INDEX CONCURRENTLY idx_orders_new_id ON orders (new_id);
-- 4. 切换主键(需要短暂停机窗口)
BEGIN;
ALTER TABLE orders DROP CONSTRAINT orders_pkey;
ALTER TABLE orders ADD PRIMARY KEY USING INDEX idx_orders_new_id;
ALTER TABLE orders DROP COLUMN id;
ALTER TABLE orders RENAME COLUMN new_id TO id;
COMMIT;
五、B-tree Skip Scan:复合索引的新玩法
5.1 什么是Skip Scan?
在PostgreSQL 18之前,复合索引(多列索引)在某些查询模式下无法被充分利用。考虑以下索引和查询:
CREATE INDEX idx_status_created ON orders (status, created_at);
-- 这个查询可以使用索引
SELECT * FROM orders WHERE status = 'pending' AND created_at > '2026-01-01';
-- 但这个查询无法使用索引(缺少status的等值条件)
SELECT * FROM orders WHERE created_at > '2026-01-01';
在PostgreSQL 18中,B-tree Skip Scan允许数据库在缺少前导列等值条件时,通过"跳跃"索引的前导列来使用复合索引:
索引结构(status, created_at):
pending → [2026-01-01, 2026-01-15, 2026-02-01, ...]
shipped → [2026-01-05, 2026-01-20, 2026-03-01, ...]
cancelled → [2026-01-10, 2026-02-15, ...]
Skip Scan 执行流程:
1. 跳到 pending 区域,扫描 created_at > '2026-01-01' 的记录
2. 跳到 shipped 区域,扫描 created_at > '2026-01-01' 的记录
3. 跳到 cancelled 区域,扫描 created_at > '2026-01-01' 的记录
4. 合并结果
5.2 何时受益?
Skip Scan在以下条件下最有效:
- 前导列的基数(Cardinality)较低:如状态、类型、地区等枚举字段
- 前导列的唯一值较少:如果有几千个不同的值,Skip Scan的优势就不明显了
- 查询条件只涉及索引的后续列
-- 典型受益场景:低基数前导列
CREATE INDEX idx_region_sales ON sales (region, sale_date, amount);
-- 按日期查询所有地区的销售数据
SELECT * FROM sales WHERE sale_date BETWEEN '2026-01-01' AND '2026-01-31';
-- PostgreSQL 18: Skip Scan → 使用索引
-- PostgreSQL 17: 全表扫描(无法使用复合索引)
六、pg_upgrade保留统计信息:让大版本升级不再痛苦
6.1 旧版本的痛点
在PostgreSQL 18之前,执行 pg_upgrade 进行大版本升级后,所有表的统计信息都会丢失。这意味着升级完成后,查询优化器没有数据分布的先验知识,会生成次优的执行计划。你必须在升级后立即运行 ANALYZE 来重新收集统计信息,而对于大型数据库来说,这个过程可能需要几个小时。
6.2 PostgreSQL 18的改进
PostgreSQL 18 的 pg_upgrade 现在会自动保留统计信息。这意味着:
- 升级完成后,查询优化器立即拥有准确的统计数据
- 不需要紧急运行
ANALYZE - 升级窗口可以大幅缩短
- 升级后的第一个查询就能获得优化的执行计划
# PostgreSQL 18 的升级流程(简化版)
pg_upgrade \
--old-datadir=/var/lib/postgresql/17/data \
--new-datadir=/var/lib/postgresql/18/data \
--old-bindir=/usr/lib/postgresql/17/bin \
--new-bindir=/usr/lib/postgresql/18/bin
# 升级完成后,统计信息已经保留,无需立即运行ANALYZE
# 可以在业务低峰期再运行一次ANALYZE以获取最新数据
七、OAuth 2.0认证支持:拥抱企业级SSO
7.1 背景
在企业环境中,数据库的身份认证一直是个痛点。传统的密码认证方式存在以下问题:
- 密码管理复杂(轮换、强度要求)
- 无法与企业SSO系统集成
- 审计困难
- 多因素认证(MFA)支持缺失
7.2 PostgreSQL 18的OAuth 2.0支持
PostgreSQL 18新增了OAuth 2.0认证方式,可以与企业级身份提供商(IdP)集成:
-- pg_hba.conf 配置示例
# TYPE DATABASE USER ADDRESS METHOD
host all all 0.0.0.0/0 oauth issuer=https://auth.example.com scope=openid
支持的OAuth 2.0流程:
- Authorization Code Flow:用于交互式客户端
- Client Credentials Flow:用于服务间通信
- Device Authorization Flow:用于CLI工具
这意味着你可以用Okta、Azure AD、Keycloak等身份提供商来管理PostgreSQL的访问权限,实现真正的企业级单点登录。
八、其他值得关注的特性
8.1 pg_stat_statements 增强
-- 新增 I/O 统计信息
SELECT query, calls, total_exec_time,
shared_blks_read, shared_blks_written,
local_blks_read, local_blks_written,
temp_blks_read, temp_blks_written
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;
8.2 COPY命令增强
-- 支持ON ERROR选项,跳过格式错误的行
COPY my_table FROM '/data/import.csv'
WITH (FORMAT csv, ON_ERROR ignore);
-- 统计跳过的错误行数
-- 返回: COPY 10000, with 15 errors
8.3 EXPLAIN增强
-- EXPLAIN ANALYZE现在显示更多I/O统计信息
EXPLAIN (ANALYZE, BUFFERS, WAL)
SELECT * FROM large_table WHERE status = 'active';
-- 输出中新增:
-- I/O Timings: Read=12.345ms Write=0.123ms
-- AIO Requests: 42 (batched=5)
8.4 MERGE语句增强
-- MERGE现在支持RETURNING子句
MERGE INTO target_table t
USING source_table s ON t.id = s.id
WHEN MATCHED THEN UPDATE SET t.value = s.value
WHEN NOT MATCHED THEN INSERT (id, value) VALUES (s.id, s.value)
RETURNING merge_action(), t.*;
九、生产环境升级实战指南
9.1 升级前检查清单
# 1. 检查当前版本
psql -c "SELECT version();"
# 2. 检查所有扩展兼容性
psql -c "SELECT * FROM pg_available_extensions WHERE installed_version IS NOT NULL;"
# 3. 检查是否有不兼容的变更
# 参考: https://www.postgresql.org/docs/18/release-18.html
# 4. 运行兼容性检查
pg_upgrade --check \
--old-datadir=/var/lib/postgresql/17/data \
--new-datadir=/var/lib/postgresql/18/data \
--old-bindir=/usr/lib/postgresql/17/bin \
--new-bindir=/usr/lib/postgresql/18/bin
9.2 升级步骤
# 1. 停止旧版本
sudo systemctl stop postgresql@17-main
# 2. 执行升级
sudo -u postgres pg_upgrade \
--old-datadir=/var/lib/postgresql/17/data \
--new-datadir=/var/lib/postgresql/18/data \
--old-bindir=/usr/lib/postgresql/17/bin \
--new-bindir=/usr/lib/postgresql/18/bin \
--link # 使用硬链接加速,节省磁盘空间
# 3. 启动新版本
sudo systemctl start postgresql@18-main
# 4. 更新统计信息(可选,但建议在低峰期执行)
sudo -u postgres vacuumdb --all --analyze-in-stages
9.3 性能调优建议
-- 启用异步I/O(Linux)
ALTER SYSTEM SET io_method = 'io_uring';
ALTER SYSTEM SET effective_io_concurrency = 200; -- NVMe SSD
ALTER SYSTEM SET io_combine_limit = '256kB';
-- UUIDv7相关
-- 无需特别配置,uuidv7()函数默认可用
-- 虚拟生成列
-- 无需特别配置,直接在表定义中使用
-- 重载配置
SELECT pg_reload_conf();
十、总结与展望
PostgreSQL 18是一次里程碑式的版本更新。异步I/O子系统从根本上改变了数据库与存储层的交互方式,带来了实实在在的性能提升;虚拟生成列填补了SQL标准层的功能空白,让表设计更加灵活;UUIDv7的原生支持则解决了困扰开发者多年的主键选择难题。
从更宏观的视角来看,PostgreSQL 18的这些变化反映了一个清晰的趋势:PostgreSQL正在从一个传统的关系型数据库,演进为一个能够适应AI时代需求的通用数据平台。原生向量搜索的支持、OAuth 2.0的企业级认证、异步I/O对现代存储硬件的充分利用——这些都表明PostgreSQL的野心远不止于"世界上最先进的开源关系型数据库"。
对于开发者和DBA来说,现在是升级到PostgreSQL 18的好时机。异步I/O带来的性能提升是"免费"的,UUIDv7让你不再需要在分布式唯一性和索引性能之间做取舍,虚拟生成列让你的表设计更加优雅。唯一的建议是:在升级前做好充分的测试,特别是检查所有扩展的兼容性。
PostgreSQL 19已经在路上了。根据社区的讨论,未来的方向包括:异步WAL写入、更完善的向量搜索能力、以及对AI工作负载的进一步优化。让我们拭目以待。
参考资源: