极慢的 Netezza(数据库)批量插入
Posted
技术标签:
【中文标题】极慢的 Netezza(数据库)批量插入【英文标题】:Extremely Slow Netezza (Database) Batch Inserts 【发布时间】:2015-10-12 16:25:08 【问题描述】:我正在使用批量插入和准备好的语句将数据插入到 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
有谁知道如何加快速度?
【问题讨论】:
“极慢”需要多长时间?您期望的加载时间是多少?将数据插入数据仓库需要时间。 第二个吉尔伯特的请求。您的这批 1000 批产品实际上是什么时候获得的? @GilbertLeBlanc 使用上面的代码,我每秒可以得到大约 1-2 行。 【参考方案1】:插入语句批处理不会在Netezza
上执行,每个查询的开销将限制这些操作的效率。我建议将您的数据转储到平面文件并执行nzload
/external table insert
示例请参考Transient External Tables。
【讨论】:
使用瞬态外部表让它工作。谢谢!【参考方案2】:您可能已经知道,Netezza JDBC 驱动程序可能会检测到批量插入,并在幕后将其转换为外部表加载。
从这里的示例运行时可以看出,使用非批处理准备语句的单例插入非常慢,而使用 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。
一个重要的诊断点是检查 JDBC 跟踪或 Netezza 系统上的 pg.log,以验证是否正在为您隐式调用外部表。
如果您看到这样的条目,那么您没有通过 JDBC 驱动程序获得隐式外部表的好处。
2015-08-08 12:52:50.640127 EDT [13898] DEBUG: QUERY: insert into testload (c1,c2) values (next value for testload_seq, 96)
如果您看到这样的条目,那么您将获得一个外部表。
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);
【讨论】:
我只有 32k 行,即使将批处理大小设置为 10k,按照我的速度也需要几个小时才能完成。 在这种情况下,您肯定不会得到隐式的外部表行为。也许是因为启用了自动提交? @JohnRoberts 我面临同样的问题,我不得不插入数百万条记录,并且我尝试使用 10 K 和 100 K 的批量大小。仍然需要几个小时才能完成。自动提交是错误的。我应该怎么做才能获得隐式外部表行为?以上是关于极慢的 Netezza(数据库)批量插入的主要内容,如果未能解决你的问题,请参考以下文章