首推使用copy批量写入数据,JDBC等驱动也支持copy方式,如copyManager方法;其次推荐batch insert批量提交,或insert 多values方式,可以减少应用至CN、DN节点交互的网络开销;不推荐单条insert提交写法,效率最差。
例如,在虚拟机上,模拟写入200000行记录测试结果,结果显示:copy写入是单条insert的2000倍以上。
表结构:
create table teledb(id int, info varchar(32), crt_time timestamp);
写入方式 | 效率 | 耗时 | 语法示例 | 说明 |
---|---|---|---|---|
single insert | 最慢 | 438s | for (int i=0; i < total_row; i++){ String sql = String.format("insert into test values(%d, 'init', now())", i); stmt.executeUpdate(sql); } |
每插入一条数据需要提交一次,数据库交互较多。 |
batch insert | 较快 | 3.16s | for (int i = 0; i < total_row; i++) { stmt.setInt(1, i); stmt.setString(2, "test_prepared"); stmt.addBatch(); if (i % g_batch == 0) { stmt.executeBatch(); stmt.clearBatch(); } } |
批量插入类似于多值插入,减少了数据库交互: insert into test values(1,'test'),(2,'test2') .... |
copy insert | 最快 | 0.21s | for (int i=0; i < total_row; i++){ buf.append(i + delimiter+ "test" + delimiter + "2021-05-25" + "\r\n" ); } StringReader reader = new StringReader(buf.toString()); copyManager.copyIn("COPY public.test FROM STDIN WITH DELIMITER ';'", reader); |
copy 将插入的数据组合为二进制流,通过流的方式导入表。走 copy 协议,数据库交互最少。 |