如何缩短Liquibase迁移PostgreSQL数据的执行时间?
用批量INSERT替代单条插入
别写30万条独立的INSERT INTO table (col1, col2) VALUES (val1, val2);,改成一次插入多行值的批量写法,比如每次插500-1000条:INSERT INTO table (col1, col2) VALUES (val1, val2), (val3, val4), ..., (valN, valM);这种方式能大幅减少数据库的网络交互和事务开销,提速明显。
调整Liquibase的提交和日志设置
Liquibase默认可能每条语句单独提交,要改成批量提交。在changelog的<changeSet>里加上autoCommit="false",然后在脚本末尾手动加COMMIT;。同时把Liquibase的日志级别调到WARN,关掉冗余的日志输出,减少IO消耗。临时禁用约束和非主键索引
插入数据时,数据库会逐条检查外键、唯一约束,还会实时更新索引,这是拖慢速度的关键。可以先禁用这些:-- 禁用所有触发器(含外键约束检查) ALTER TABLE your_table DISABLE TRIGGER ALL; -- 删除非主键索引 DROP INDEX IF EXISTS idx_your_table_col;等数据全部插入完成后,再重新启用:
ALTER TABLE your_table ENABLE TRIGGER ALL; CREATE INDEX idx_your_table_col ON your_table (col);用PostgreSQL的COPY命令或Liquibase的loadData
COPY是PostgreSQL专门为批量导入设计的命令,速度比INSERT快一个量级。可以把数据存成CSV,然后用Liquibase执行:COPY your_table (col1, col2) FROM '/path/to/your_data.csv' WITH (FORMAT csv, HEADER);嫌生成CSV麻烦的话,直接用Liquibase的
<loadData>标签,它底层会调用COPY,配置起来更简单:<loadData tableName="your_table" file="classpath:your_data.csv" separator=","> <column name="col1" type="STRING"/> <column name="col2" type="INTEGER"/> </loadData>临时调优PostgreSQL参数
给数据库临时加些资源,提升写入性能:-- 增大排序操作可用内存 SET work_mem = '64MB'; -- 增大WAL日志的最大尺寸,减少检查点频率 SET max_wal_size = '2GB'; -- 增大维护操作可用内存(重建索引时用) SET maintenance_work_mem = '128MB';数据导入完成后再把这些参数改回原值就行。
拆分大ChangeSet
别把30万条数据塞进一个ChangeSet里,分成几个小的,每个处理5-10万条。这样能避免Liquibase在内存中处理过大的数据集,也降低了事务回滚的风险。
内容的提问来源于stack exchange,提问作者Peter Penzov

