【问题标题】:JDBC fastload - OutOfMemory after 20 million addBatch() operationsJDBC 快速加载 - 2000 万次 addBatch() 操作后内存不足
【发布时间】:2011-12-02 20:31:17
【问题描述】:

我正在使用 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() - 遍历文件,每 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 时出错”。

谁能解释我应该如何加载 1 亿行?

是否缺少我的配置(例如,告诉驱动程序定期推送一些更新而不是将它们保存在内存中)?

谢谢,

一个。

【问题讨论】:

  • 你的陈述是什么样的?
  • 在 Teradata 的开发人员交流中,您的问题似乎有答案。如果那里的解决方案是正确的,请在此处更新此问题。 (我讨厌松散的结局......):)

标签: jdbc teradata out-of-memory


【解决方案1】:

在 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();**

像魅力一样工作。

FAQ 中唯一没有 100% 清楚的是块大小。 它说一些令人困惑的内容,例如“与您的 JVM 堆可以承受的一样大”以及“将来我们会建议将其设置为 50K-100K。这两者似乎相互矛盾,我已将其设置为 1000 万,它是工作发现。

另外 - Teradata JDBC 中显然有一个 CSV 快速加载器功能 - 请参阅 http://developer.teradata.com/doc/connectivity/jdbc/reference/current/jdbcug_chapter_2.html#BABFGFA2 - 通常可以提供更好的性能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    • 2017-10-19
    • 2021-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多