用Java快速将数据导入mysql

Posted

技术标签:

【中文标题】用Java快速将数据导入mysql【英文标题】:Fast import data to mysql in Java 【发布时间】:2016-04-21 23:36:11 【问题描述】:

通过 Java 代码将大约 500.000 条记录从 CSV 文件插入 mysql 数据库需要多长时间?托管在本地主机上的数据库。

表结构:AI id, | varchar(8) | datetime | int | varchar(2)。我的代码需要在 40 分钟内插入 70.000 条记录。有什么方法可以更快地做到这一点吗? 这是我的代码的主要部分:

CsvReader pro

ducts = new CsvReader(path);
products.readHeaders();
stmt = con.createStatement();
String updateString = "INSERT INTO table (T_V1, date, T_V2, T_V3) VALUES (?,?,?,?)";
PreparedStatement preparedStatement = con.prepareStatement(updateString);

            while (products.readRecord()) 
                v1= products.get("V1");
                date = format.parse(products.get("Date") + " " + products.get("Hour"));
                java.sql.Date dateDB = new java.sql.Date(data.getTime());
                v2 = products.get("V2");
                v3 = products.get("V3");



                preparedStatement.setString(1, v1);
                preparedStatement.setDate(2,dateDB);
                preparedStatement.setInt(3, Integer.parseInt(v2));
                preparedStatement.setString(4, v3);   
                preparedStatement.executeUpdate();
            

根据您的建议,我将语句的创建移出循环。在我有 29 rps 之后,现在我每秒有 33 条记录。

【问题讨论】:

将语句的创建移出while循环 你不应该使用Java导入数据,使用mysqlimport实用程序。 曾经我不得不将基于pcap 文件的数百万条记录插入数据库。将数据分成块并使用线程运行它要快得多。不知道它在 MySQL 中是如何工作的。我使用 Oracle DB,并让生产者线程创建表类型(代表一组数据库记录),让消费者线程创建数据库事务并使用这些表类型参数调用存储过程,将数据插入数据库。但一般来说,如果你已经有 CSV 文件,最快的方法是使用一些 SQL Loader 替代品dev.mysql.com/doc/refman/5.1/en/load-data.html 按照建议,在循环外仅创建一次 PreparedStatement,此外,请考虑按照 this post 中的建议使用批量插入 (preparedStatement.addBatch())。 我将语句的创建移出循环。不幸的是,我不得不用 Java 来做这件事 【参考方案1】:

如果不需要使用Java插入代码,可以使用SQL插入数据。

在您的 GUI 工具(SQLyog 等)中使用以下代码:

LOAD DATA LOCAL INFILE 'D:\\Book1.csv' INTO TABLE table_name FIELDS TERMINATED BY ','    
ENCLOSED BY '"' LINES TERMINATED BY '\r\n' (column_name1, column_name2);

【讨论】:

【参考方案2】:

我可能会选择使用 MySQL 中的 LOAD DATA 语句而不是使用 Java:

LOAD DATA LOCAL INFILE '/path/to/your/file.csv' INTO TABLE table;

这将避免您当前的大量开销,假设您在将每一行插入 MySQL 之前对其进行处理。

您可以使用原始 JDBC 从 Java 执行 LOAD DATA 语句。

【讨论】:

但是 OP 明确要求通过 Java 传递。 如果 OP 对此使用 Java 的预感是错误的,这将毫无意义。 LOAD DATA 是加载大量数据的首选工具,如果可以的话。 OP 在 cmets 中确认该解决方案需要使用 Java。 当然,我没想到可以这样!但它只有在我不必更改文件结构的任何内容时才有用,对吧? 是的。如果您需要对原始数据进行按摩,那么使用 Java 可能是最好的选择。【参考方案3】:

你应该去批量插入

    PreparedStatement prepStmt = con.prepareStatement("Insert query");
    prepStmt.setString(1,parameter1);                 
    prepStmt.addBatch();

   // for next set of parameter
    prepStmt.setString(1,parameter2);                        
    prepStmt.addBatch();

    int [] numUpdates=prepStmt.executeBatch()

)

见Which is faster: multiple single INSERTs or one multiple-row INSERT?

How to do a batch insert in MySQL

【讨论】:

【参考方案4】:

不要在while 内部创建PreparedStatement,而是在外部创建PreparedStatement 并简单地在while 循环内设置值。

类似

    String updateString = "INSERT INTO table (T_V1, date, T_V2, T_V3) VALUES (?,?,?,?)";
    PreparedStatement preparedStatement = con.prepareStatement(updateString);
    while (products.readRecord()) 
            v1= products.get("V1");
            date = format.parse(products.get("Date") + " " + products.get("Hour"));
            java.sql.Date dateDB = new java.sql.Date(data.getTime());
            v2 = products.get("V2");
            v3 = products.get("V3");

            preparedStatement.setString(1, v1);
            preparedStatement.setDate(2,dateDB);
            preparedStatement.setInt(3, Integer.parseInt(v2));
            preparedStatement.setString(4, v3);   
            preparedStatement.executeUpdate();
        

此外,您应该提交数据库引擎内存可以处理的每一行,否则在一定数量的插入后系统会非常慢。

请注意,通常应该可以在 40 分钟内创建超过 70.000 条记录。可能您的网络存在瓶颈。它是 java 应用程序的本地数据库还是远程服务器?如果是远程服务器,请检查连接速度。

【讨论】:

本地数据库【参考方案5】:

首先,您可以在循环之外创建准备好的语句。您还可以重构代码以使用多线程,因为您的插入语句似乎不相互依赖,因此您可以通过并行拆分来处理所有数据。

但是对于您的问题“多久...”没有绝对的答案。 这取决于托管 mysql 的机器和执行 java 代码的机器:核心数、可用内存等。

【讨论】:

我把它移出了循环。我知道没有答案,但我认为有可能做得更快,所以我做错了。多线程对我来说可能太高了:) 但是,谢谢你的回复

以上是关于用Java快速将数据导入mysql的主要内容,如果未能解决你的问题,请参考以下文章

如何快速导入大SQL文件到MySQL数据库

用java怎么将excel表格数据导入到mysql数据库中

1200万 mysql数据怎么快速导入到Mongodb

用java怎么将excel表格数据导入到mysql数据库中

mysql文件导入现有数据库表中

几个CSV大文件如何导入mysql数据库,并更新替换对应数据?