PG 19 让 COPY 导入数据吃上 SIMD 红利性能飙升
本期播客
PG 19 COPY FROM CSV 数据导入吃上 SIMD 红利
你以为 COPY FROM 慢,瓶颈一定在磁盘?
未必。很多时候,磁盘还没喊累,CPU 已经在逐字节啃 CSV 了。
2026 年 3 月 13 日,PostgreSQL 提交了一个很容易被低估、但对 DBA、架构师、应用开发者都很有现实意义的补丁:
e0a3a3fd5361913502ff696ecf47770ca55975ae
标题很直接:Optimize COPY FROM (FORMAT {text,csv}) using SIMD
如果把这句话翻成大白话,就是:
PostgreSQL 不想再老老实实一字节一字节扫文本导入数据了,而是开始让 CPU 一次并行检查一大块字符。
这不是“小修小补”。
这是在改 PostgreSQL 最常见数据入口之一的底层热路径。
而我要先抛出核心观点:
未来数据库导入性能的上限,越来越不只取决于存储吞吐,还取决于你能不能把“文本解析”这件事从标量时代带进 SIMD 时代。
一、很多人对 COPY FROM 的理解,已经过时了
在 DBA 和开发者的语境里,COPY FROM 往往被当成一句经验:
比单条 INSERT快比 ORM 批量写快 是 PostgreSQL 最推荐的大批量导入方式之一
这些都没错。
PostgreSQL 官方文档也明确把 COPY 定义为在表与文件/标准输入之间高效搬运数据的机制,并提供了 pg_stat_progress_copy 来跟踪进度。
但问题在于,很多人停在这里,不再往下想。
真正的问题是:
当 COPY FROM FORMAT text/csv 已经不用一条条 SQL 插入后,它下一步的瓶颈会落在哪?
答案通常不是一个,而是两类:
I/O:数据读进来够不够快 CPU:读进来之后,解析 text/csv 够不够快
而这次 commit 针对的,正是第二类。
PostgreSQL 2026 年度大戏来了, 扫海报中的二维码报名, 选择早鸟或通票(都含午餐和周边礼品), 可私信我要优惠码, 数量有限先到先得!
二、PostgreSQL 之前是怎么干的?一句话:逐字节扫描
根据 PostgreSQL 内核实现和 DeepWiki 对 copyfromparse.c 的总结,COPY FROM text/csv 的关键路径之一,是在输入缓冲区里寻找各种“特殊字符”:
分隔符 引号 转义字符 行结束符 某些特殊结束标记
过去的主路径,本质上是:
一字节一字节扫,看看这个字符是不是“特殊字符”。
这件事听上去平平无奇,甚至很合理。
但在今天的硬件条件下,它会暴露一个非常现实的问题:
CSV 解析不是“高深逻辑”,但它极容易成为 CPU 热点。
为什么?
因为它的操作太频繁了:
每行都要扫 每列都要判 每个字符都可能触发分支 还要维护引号/转义状态
这类逻辑有个典型特征:
单次不贵,次数极多;每步简单,但总量惊人。
一旦你的导入规模上来,比如:
几千万行 上亿行 长字段 多列文本 网络和磁盘都不算慢
CPU 就可能比磁盘更早成为主矛盾。
三、这次优化到底做了什么?本质是“跳过无聊数据”
这次 commit 的核心思想非常漂亮:
既然大多数文本内容并不是特殊字符,那就别每个字节都认真审问。
改法是:
用 SIMD 指令一次检查一大块数据 如果这块里没有特殊字符,就整块跳过 只有发现特殊字符附近时,再退回更细粒度处理
这就是所谓的“SIMD skip over chunks without special characters”。
你可以把它理解成两种工作方式的区别:
旧方式:
保安逐个翻每个人口袋,确认有没有违禁品。
新方式:
先用高效安检门快速扫一批人,没响的一整批直接过,响了再单独查。
这才是现代 CPU 最擅长的事。
四、为什么这是大事?因为文本导入的瓶颈,越来越像“解析问题”而不是“写盘问题”
很多数据库从业者还停留在老时代直觉里:
导入慢,多半是磁盘差 导入快不起来,多半是 WAL 大 调快导入,就是关约束、关索引、改 checkpoint
这些判断有时对,但越来越不完整。
从第一性原理看,COPY FROM text/csv 的总成本,至少包含四段:
读取原始输入 文本解析与字段切分 数据类型转换 堆写入、WAL、索引、约束、触发器
如果你面对的是现代服务器:
NVMe 很快 页缓存很强 内存足够 文件来源本地或高带宽网络 表上索引不多、约束不重
那么主矛盾就可能前移到第 2 步:
文本解析本身。
所以这次优化重要,不是因为它让 COPY “终于变快”,
而是因为它承认了一件很多人不愿承认的现实:
纯文本格式的导入,在很多场景下已经不是 I/O 问题,而是 CPU 解析问题。
五、哪些场景最吃这波红利?哪些场景别高兴太早?
这篇文章最重要的部分,不是喊“SIMD 牛”,而是把边界说清楚。
最可能受益的场景
根据 commit 描述和 PostgreSQL COPY 的解析规则,最容易受益的是这类数据:
行比较长 大段内容没有特殊字符 引号、转义较少 CSV 字段内容相对“干净” 分隔符密度不算过高 文本导入量极大,CPU 成本可累计放大
为什么?
因为 SIMD 路径最擅长做的,就是:
快速跳过“绝大多数都很普通”的数据块。
如果一整段字符里没有分隔符、引号、转义符、特殊终止符,那么传统逐字节循环几乎是在浪费 CPU。
SIMD 则能把这段“无聊工作”压缩掉。
受益有限,甚至可能不明显的场景
这次 commit 自己也写得很保守:
为了避免回归,一旦遇到短行或某些特殊字符,SIMD 会对本次 COPY FROM 剩余部分禁用,策略偏保守,未来也许还能更激进。
这句话很关键,意味着以下场景不要盲目乐观:
行很短 引号很多 转义很多 CSV 数据很“脏”,特殊字符频繁出现 每行很快就碰到 delimiter/quote/escape 复杂 CSV,经常出现带换行的 quoted field
这种数据模式下,SIMD 很难长时间沿着“整块跳过”快路径奔跑,
很快就要退回普通解析逻辑。
换句话说:
这次优化奖励的是“结构规整、可预测、长段普通字符”的数据。
它不会神奇地把所有脏 CSV 都变快。
六、这不是“所有导入都飞起”,更不是“以后 CSV 可以随便用了”
必须把这层说透。
有些人看到 SIMD,会马上得出两个错误结论:
误判 1:既然 COPY FROM csv 变快了,那文本格式就够了,不用考虑 binary
错。
PostgreSQL 官方文档一直说得很清楚:binary 格式通常会比 text/csv 更快,只是可移植性和通用性更差。
所以更准确的判断是:
如果你要通用、跨系统、跨语言、方便排查,text/csv 仍然有巨大现实价值 如果你追求极致吞吐,而且上下游都可控,binary 依然可能更强
SIMD 优化提升的是 text/csv 的竞争力,不是抹平它与 binary 的物理差异。
误判 2:内核都优化了,开发者不用关心数据格式质量了
也错。
这次优化恰恰在提醒你:
数据“干净不干净”“规整不规整”,已经不只是 ETL 美学问题,而是 CPU 成本问题。
如果你的 CSV:
引号乱飞 转义过多 每列塞大段复杂文本 行格式高度不稳定
那你就是在主动破坏 SIMD 能发挥作用的前提。
所以从架构角度看,这个 commit 传递的是一个更深的观点:
导入性能,不只是数据库问题,也是数据生产格式的问题。
七、对 DBA、架构师意味着什么?
这次 commit 对 DBA 和架构师的启发,远大于“某个导入任务快一些”。
1. 版本升级的收益,越来越来自热路径瘦身
很多团队评估 PostgreSQL 升级,还停留在这几项:
新 SQL 语法 新索引特性 planner 增强 高可用能力
这些当然重要。
但现代 PostgreSQL 真正越来越值钱的一类改动,是这种:
AIO SIMD executor 热路径优化 tuple deformation 优化 maintenance I/O 重构
也就是说:
数据库版本升级的回报,已经越来越多地来自“基础路径更现代化”,而不是“多了一个功能按钮”。
2. COPY FROM 的性能分析,要更细分
以后再看导入慢,不该只问:
磁盘是不是慢 WAL 是不是大 checkpoint 是不是顶住了
还应该问:
CPU 火焰图上,解析占了多少 输入数据是不是大量短行 CSV 是否充满引号/转义 实际瓶颈是 parse、cast 还是 heap/WAL
因为这次补丁已经证明:
PostgreSQL 社区自己也承认,COPY FROM 的解析阶段值得单独优化。
这会反过来影响 DBA 的排障思路。
八、对应用开发者意味着什么?
对开发者,这个 commit 其实是一次很直接的提醒:
你提交给数据库的,不只是“数据”,还是“解析负担”。
很多团队在数据导入链路上有个错误习惯:
只关心能不能导进去 不关心格式是否利于解析 只要 CSV 合法就行 上游系统输出怎么方便怎么来
这在规模小时问题不大,
但一旦进入亿级、十亿级导入,问题就很明显:
数据库并不是“读到文件就自动落表”,而是要逐层解析、切字段、转类型、写 WAL。
所以开发者应该从这次 commit 里得到三个实用结论:
如果必须用 CSV,尽量让格式规整,少做无意义 quoting/escaping 如果是系统内部大批量交换,认真评估 binary 或更可控的管道格式 如果你抱怨导入慢,别先骂数据库,先看看上游吐出来的是不是“解析噩梦”
九、第一性原理:什么时候这次优化最值钱?
这篇文章的核心判断,建立在几个前提上。
前提 1:你的 COPY FROM 使用的是 text/csv
因为这次 commit 明确针对的是 FORMAT {text,csv}。
不是 binary,不是其他路径。
前提 2:瓶颈里确实有显著的“逐字符解析成本”
如果你的慢主要来自:
复杂类型转换 唯一索引冲突 触发器 外键检查 WAL fsync 网络传输
那 SIMD 再强,也救不了主矛盾。
前提 3:输入数据具有足够长的“普通字符区间”
也就是特殊字符不能太密。
否则 SIMD 快路径根本跑不起来,或很快被禁用。
如果这三个前提同时成立,
这次优化就很有现实意义。
十、如果前提崩了,观点也必须变
这是专业分析和流量文章的分水岭。
如果你的数据是“脏 CSV”
那正确观点不是“PostgreSQL SIMD 不给力”,
而是:
数据模式先天不利于向量化跳过,收益本来就会受限。
如果你的瓶颈在 WAL 或约束
那这次优化的意义就会退居二线。
此时更该优化的是:
减少索引 批量装载策略 COPY FREEZE可行性关闭非必要触发器 分区装载 调整 checkpoint / wal / autovacuum 协同
如果你本来就用 binary
那这次补丁对你影响不大。
但它依然说明一个趋势:
PostgreSQL 正在连 text/csv 这种“传统、通用、最难极致优化”的入口都拿 SIMD 开刀。
这说明社区在认真追求“默认路径也更快”。
结论
这次 Optimize COPY FROM (FORMAT {text,csv}) using SIMD,不是一个只属于内核开发者的补丁。
它对业务的真正意义是:
PostgreSQL 正在把最常见的数据导入入口,从“逐字节文本处理”推进到“现代 CPU 友好的并行扫描”。
这背后最值得记住的,不是 SIMD 这个词本身,
而是三个现实判断:
导入性能的瓶颈,不一定在磁盘,也可能在文本解析 数据格式质量,不只是兼容性问题,也是吞吐问题 未来 PostgreSQL 的版本价值,会越来越体现在这种底层热路径优化上
所以,对 DBA、架构师、开发者来说,这个 commit 最值得记住的一句话是:
数据库不只是要写得快,还要“看懂文本”更快。
你怎么看
你们线上大批量导入时,主要瓶颈更常出现在哪一层:I/O、WAL、约束,还是文本解析?
如果 PostgreSQL 的 COPY FROM csv 越来越快,你会继续坚持 CSV 通用格式,还是会更认真考虑 binary/自定义导入协议?
评论区聊聊:你觉得“数据格式设计”在导入性能里,应该背多大锅?