繁体   English   中英

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

[英]Is a “Load DATA” without a file (i.e., in memory) possible for MySQL and Java?

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

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

非常感谢,Joerg。

似乎从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主题) 的用法

希望这一切都有帮助。

干杯

丰富

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

@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);                 
            }
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM