极慢的 Netezza(数据库)批量插入

Extremely Slow Netezza (Database) Batch Inserts

我正在使用批量插入和准备好的语句将数据插入 Netezza。但是,性能极其缓慢。下面是我的代码:

final int batchSize = 1000;
int count = 0;
for (final MyClass object: myList) {
    ps.setString(1, object.getOne());
    ps.setString(2, object.getTwo());
    ps.setString(3, object.getThree());
    ps.setString(4, object.getFour());
    ps.setString(5, object.getFive());
    ps.setString(6, object.getSix());
    ps.setString(7, object.getSeven());
    ps.setString(8, object.getEight());
    ps.setString(9, object.getNine());
    ps.setString(10, object.get10());
    ps.addBatch();
    if(++count % batchSize == 0) {
        ps.executeBatch();
    }
}
ps.executeBatch(); // insert remaining records

有谁知道我怎样才能加快速度?

插入语句批处理将不会执行Netezza每个查询的开销将限制这些操作的效率。我建议将您的数据转储到平面文件并执行 nzload/external table insert 示例请参考 Transient External Tables.

您可能已经知道,Netezza JDBC 驱动程序可能会检测到批量插入,并在幕后将其转换为外部 table 加载。

正如您从示例 运行times here 中看到的那样,使用非批处理准备语句的单例插入非常慢,而使用 executebatch 的插入 运行 随着批处理的扩展而快速扩展尺寸。

start of call to testSingletonInserts() with batchSize = 100
exec time for batch-size 100: 8193ms
end of call to testSingletonInserts()

start of call to testBatchInserts() with batchSize = 1000
exec time for batch-size 1000: 190ms
end of call to testBatchInserts()

start of call to testBatchInserts() with batchSize = 10000
exec time for batch-size 10000: 734ms
end of call to testBatchInserts()

start of call to testBatchInserts() with batchSize = 100000
exec time for batch-size 100000: 1763ms
end of call to testBatchInserts()

一般来说,我不会推荐小于 10,000 的批量大小。

一个重要的诊断点是检查 Netezza 系统上的 JDBC 跟踪或 pg.log 以验证外部 table 正在为您隐式调用。

如果您看到这样的条目,那么您没有通过JDBC驱动程序获得隐式外部table的好处。

2015-08-08 12:52:50.640127 EDT [13898]  DEBUG:  QUERY: insert into testload (c1,c2) values (next value for testload_seq, 96)

如果您看到这样的条目,那么您收到的是外部 table。

2015-08-08 12:52:51.078404 EDT [13898]  DEBUG:  QUERY: CREATE EXTERNAL TABLE bulkETL_13898_0 ( c0 nvarchar(5) )  USING (  DATAOBJECT('/tmp/junk')  REMOTESOURCE 'jdbc'  DELIMITER '     '  ESCAPECHAR ''\'  CTRLCHARS 'YES'  CRINSTRING 'YES'  ENCODING 'INTERNAL'  MAXERRORS 1 QUOTEDVALUE 'YES' );
2015-08-08 12:52:51.086081 EDT [13898]  DEBUG:  QUERY: insert into testload (c1,c2) values (next value for testload_seq,bulkETL_13898_0.c0)
2015-08-08 12:52:51.101234 EDT [13898]  DEBUG:  transaction 1411711 started dbos txid 0x3dc5c

如果您发现您的批处理执行没有获得隐式外部行为,请尝试确保在您的连接上关闭自动提交。

conn.setAutoCommit(false);