我正在使用Teradata jdbc驱动程序13.00.00.10,并尝试将包含1亿行的平面文件上传到teradata。
我从干净的桌子开始。
首先我尝试遍历整个文件,为每一行做addBatch(),最后只做一个executeBatch():
while ((s = reader.readLine())!=null ){
String[] columns = StringUtils.split(s, separator);
for (int j=0; j <columns.length; j++){
st.setString(j+1,columns[j]);
}
st.addBatch();
i++;
if (i % 10000 ==0 ){
ULogger.info(this, "imported " + i + " lines.");
}
}
st.executeBatch();
这会快速消耗我的应用程序的所有内存。
我设置了9GB的XMX,并在大约4000万的addBatch()之后得到了OutOfMemory。
然后我尝试定期执行executeBatch() - 迭代throgh文件,每2000万个addBatch()执行一次executeBatch()。
while ((s = reader.readLine())!=null ){
String[] columns = StringUtils.split(s, separator);
for (int j=0; j <columns.length; j++){
st.setString(j+1,columns[j]);
}
st.addBatch();
i++;
if (i % 20000000 ==0 ){
st.executeBatch();
st.clearWarnings();
}
}
st.executeBatch();
在这种情况下,第一个executeBatch()成功。
但是,第二个executeBatch()失败,“启动数据库表XXX的FastLoad时出现错误”。
任何人都可以解释我应该如何加载1亿行?
是否有我缺少的配置(例如告诉驱动程序定期推送一些更新而不是将它们保存在内存中)?
谢谢,
一个。
答案 0 :(得分:2)
在Teradata用户论坛上找到答案,该论坛引导我访问常见问题解答 - (http://developer.teradata.com/connectivity/faq),其中说正确的工作方式是定期调用executeBatch() ; 但是,为了做到这一点,你需要先关闭连接上的自动提交, 并确保最终提交。
所以我的代码现在看起来像这样:
**con.setAutoCommit(false);**
while ((s = reader.readLine())!=null ){
String[] columns = StringUtils.split(s, separator);
for (int j=0; j <columns.length; j++){
st.setString(j+1,columns[j]);
}
st.addBatch();
i++;
if (i % 20000000 ==0 ){
st.executeBatch();
st.clearWarnings();
}
}
st.executeBatch();
**con.commit();**
就像一个魅力。
唯一不能从常见问题解答中100%清楚的是块大小应该是什么。 它说“像你的JVM堆可以维持的那么大”这样的东西令人困惑,而且“将来我们会建议把它设置为50K-100K。这两个似乎相互矛盾,我把它设置为1000万,它是找工作。
此外 - Teradata JDBC中显然有一个CSV快速加载器功能 - 请参阅http://developer.teradata.com/doc/connectivity/jdbc/ reference / current / jdbcug_chapter_2.html#BABFGFA2 - 这可能会提供更好的性能。