对于MySQL和Java而言,没有文件(即在内存中)的"加载数据"是可能的吗?

Jör*_*ech 8 java mysql csv load

我正在优化将~10TB的数据导入到MySQL数据库中.目前,我可以在当前的笔记本电脑上在大约14分钟内导入2.9GB(+ 0.8GB索引).该过程包括读取数据文件(Oracle".dat"导出),解析数据,将数据写入CSV文件并在其上执行"LOAD DATA LOCAL"sql命令.

是否可以提高导入速度(无需更改硬件)?有没有办法删除将文件写入文件系统并让MySQL再次读取它的步骤.是否可以将内存中的数据直接流式传输到MySQL(例如,通过JDBC驱动程序)?

非常感谢,Joerg.

Ale*_*x R 6

很难获得实际的工作代码,所以这里有一些:

@Test
public void bulkInsert() throws SQLException {
    try(com.mysql.jdbc.Connection conn = (com.mysql.jdbc.Connection) dao.getDataSource().getConnection()) {

        conn.setAllowLoadLocalInfile(true);

        try(com.mysql.jdbc.Statement stmt = (com.mysql.jdbc.Statement) conn.createStatement()) {

            stmt.execute("create temporary table BasicDbTest_1 (phone integer)");

            String data = "8675309\n";
            stmt.setLocalInfileInputStream(new ByteArrayInputStream(data.getBytes()));

            stmt.execute("load data local infile '' into table BasicDbTest_1");

            try(ResultSet rs = stmt.executeQuery("select phone from BasicDbTest_1")) {
                Assert.assertTrue(rs.next());
                Assert.assertEquals(rs.getInt(1), 8675309);                 
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Big*_*ich 5

似乎从MySQL Connector/J JDBC驱动程序版本5.1.3开始,您可以使用com.mysql.jdbc.Statement挂接InputStream引用.setLocalInfileInputStream()方法,在Java代码内部,将内存中格式化的字符串/文本"管道"到"LOAD DATA INFILE"调用.这意味着您不必从内存中写出并重新读取临时文件.请参阅:

http://dev.mysql.com/doc/refman/5.1/en/connector-j-reference-implementation-notes.html(页面底部)

这篇文章还概述了这个过程:

http://jeffrick.com/2010/03/23/bulk-insert-into-a-mysql-database

O'reilly制作了一个涵盖MySQL/JDBC性能宝石的PDF,它引用了这一点.

还提到了它与Hadoop(高级Java主题)的用法.

希望这一切都有帮助.

干杯

丰富