使用 COPY 加速 PostgreSQL 批量插入

1.copy命令介紹

PostgreSQL 中的命令COPY是执行批量插入和数据迁移的强大工具。它允许快速有效地将大量数据插入表中。

COPY命令为批量插入和数据迁移提供了更简单且更具成本效益的解决方案。
可以避免使用诸如:分布式处理工具、为数据库添加更多的 CPU 和 RAM的方案或者其他的加速方案
因此,如果有一个任务需要在短时间内插入大量行,可以考虑使用COPY 命令。它可以显著加快数据迁移和载入过程。
据说PostgreSQL 16 已将 COPY 的性能提高了 300% 以上
详尽的有关copy命令的语法可参考官网

2.copy vs insert的优势

Three-Column Table
COPYINSERT (multi-line)
LoggingOne log for the entire loadOne log for each line/entry
NetworkNo latency, data is streamedLatency between inserts
ParsingOnly one parsing operationParsing overhead
TransactionSingle transactionEach insert statement is a separate transaction
Query PlanSimpler query execution planLots of different query execution plans

总而言之,COPY 速度更快,因为与多行 INSERT 语句相比,它减少了日志记录、网络延迟、解析和事务管理的开销。 它允许更简单的查询执行计划,从而实现更快、更高效的批量插入和数据迁移。 一个权衡是它需要直接访问文件系统,因此它可能并不适合所有需要插入数据的场景。 另一个权衡是持久性,COPY 生成很少的日志,并在单个事务中执行所有日志,这使得它的风险更大。

3.测量性能

创建3个测试表

test=# create table t1 (id1 bigint,id2 bigint);
CREATE TABLE
Time: 7.744 ms
test=# create table t2 (id1 bigint,id2 bigint);
CREATE TABLE
Time: 8.680 ms
test=# create table t3 (id1 bigint,id2 bigint);
CREATE TABLE
Time: 0.924 ms

向t1插入1千万笔测试资料,产生size 422MB的测试表

test=# insert into t1 select generate_series(1,10000000),generate_series(10000000,1,-1);
INSERT 0 10000000
Time: 11933.658 ms (00:11.934)
test=# select count(1),pg_size_pretty(pg_relation_size('t1')) from t1;
  count   | pg_size_pretty 
----------+----------------
 10000000 | 422 MB
 (1 row)

Time: 377.028 ms

汇出成csv文件备用

test=# \copy t2 from '/var/lib/postgresql/t1.csv';
COPY 10000000
Time: 5997.302 ms (00:05.997)

验证汇出的csv文件的数据行数与大小

postgres@pgd-prod01:~$ cat t1.csv|wc -l
10000000
postgres@pgd-prod01:~$ ls -alh|grep t1;
-rw-rw-r--  1 postgres postgres  151M Nov 18 11:26 t1.csv
test=# insert into t3 select * from t1;
INSERT 0 10000000
Time: 9811.316 ms (00:09.811)

4.结论

最后测试结果表明,COPY 命令与 INSERT 命令相比具有更高的效率,速度上的差异是相当显着的,当插入同样的1仟万笔数据时,copy费时5997.302 ms,而insert费时9811.316 ms,相较insert而言,节约40%的时间,这是在postgresql 10版本的测试,postgresql 16据说提升更多

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PostgreSQL是一种开源的关系性数据库管理系统,支持大量的数据类型和高级功能。而MyBatis是一个优秀的基于Java的持久层框架,可以将应用程序中的Java对象映射到关系数据库中。 在使用MyBatis进行 PostgreSQL 批量插入时,可以使用批处理技术来提高插入效率。具体做法是首先使用 MyBatis 的批量插入功能进行插入数据,然后再调用 PostgreSQL 中的 COPY 命令将数据批量导入数据库。 首先,在MyBatis的 Mapper.xml 文件中,我们需要定义批量插入的 SQL 语句。SQL 语句中使用foreach标签来循环插入所有数据行。具体参数可以根据需要进行调整,样例如下: ``` <insert id="batchInsert"> INSERT INTO table_name (column1, column2, ...) VALUES <foreach collection="list" item="item" separator=","> (#{item.column1}, #{item.column2}, ...) </foreach> </insert> ``` 然后,在 Java 代码中调用批量插入功能。具体代码如下: ``` SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false); try { Mapper mapper = sqlSession.getMapper(Mapper.class); for (Data data : dataList) { mapper.insert(data); } sqlSession.commit(); } finally { sqlSession.close(); } ``` 最后使用 COPY 命令进行批量导入数据。指定文件路径和分隔符,将数据文件中的内容导入到数据库中。具体代码如下: ``` COPY table_name FROM '/path/to/data.csv' WITH (FORMAT csv, DELIMITER ',', HEADER false); ``` 通过这种方式,可以有效地实现 PostgreSQL 批量插入 MyBatis 数据。同时也可以提高数据处理效率,降低系统负担。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值