在单个事务中,在mysql中存储50000条记录的最佳做法是什么

时间:2016-04-19 14:13:21

标签: java mysql load-data-infile

输入集:数千(> 10000)个csv文件,每个文件包含> 50000个条目。 输出:将这些数据存储在mysql db。

采取的方法: 读取每个文件并将数据存储到数据库中。以下是相同的代码段。请建议这种方法是否合适。

    PreparedStatement pstmt2 = null;
try 
{
pstmt1 = con.prepareStatement(sqlQuery);
result = pstmt1.executeUpdate();
con.setAutoCommit(false);
sqlQuery = "insert   into "
        + tableName
        + " (x,y,z,a,b,c) values(?,?,?,?,?,?)";
pstmt2 = con.prepareStatement(sqlQuery);
Path file = Paths.get(filename);

lines = Files.lines(file, StandardCharsets.UTF_8);
final int batchsz = 5000;
for (String line : (Iterable<String>) lines::iterator) {

    pstmt2.setString(1, "somevalue");
    pstmt2.setString(2, "somevalue");
    pstmt2.setString(3, "somevalue");
    pstmt2.setString(4, "somevalue");
    pstmt2.setString(5, "somevalue");
    pstmt2.setString(6, "somevalue");
    pstmt2.addBatch();
    if (++linecnt % batchsz == 0) {
        pstmt2.executeBatch();
    }
}
int batchResult[] = pstmt2.executeBatch();
pstmt2.close();
con.commit();

} catch (BatchUpdateException e) {
    log.error(Utility.dumpExceptionMessage(e));

} catch (IOException ioe) {
    log.error(Utility.dumpExceptionMessage(ioe));
} catch (SQLException e) {
    log.error(Utility.dumpExceptionMessage(e));
} finally {
    lines.close();
    try {
        pstmt1.close();
        pstmt2.close();
    } catch (SQLException e) {
        Utility.dumpExceptionMessage(e);
    }
}

2 个答案:

答案 0 :(得分:2)

我过去曾经使用过LOAD DATA INFILE这样的情况。

  

LOAD DATA INFILE语句将文本文件中的行读取到   桌子以非常高的速度。 LOAD DATA INFILE是对的补充   SELECT ... INTO OUTFILE。 (见第14.2.9.1节,“SELECT ... INTO   语法“。)要将表中的数据写入文件,请使用SELECT ... INTO   OUTFILE。要将文件读回表中,请使用LOAD DATA INFILE。该   FIELDS和LINES子句的语法对于两者都是相同的   声明。这两个子句都是可选的,但FIELDS必须在LINES之前   如果两者都被指定。

IGNORE数字LINES选项可用于忽略文件开头的行。例如,您可以使用IGNORE 1 LINES跳过包含列名称的初始标题行:

  

LOAD DATA INFILE'/tmp/test.txt'INTO TABLE test IGNORE 1 LINES;

http://dev.mysql.com/doc/refman/5.7/en/load-data.html

答案 1 :(得分:1)

正如@Ridrigo已经指出的那样,LOAD DATA INFILE是要走的路。根本不需要Java。

如果您的CSV格式不能直接插入数据库,您的Java代码可以重新绘制图片。使用它来重新组织/转换CSV并将其另存为另一个CSV文件,而不是将其写入数据库。

您还可以使用Java代码遍历包含CSV的文件夹,然后执行

的系统命令
Runtime r = Runtime.getRuntime();
Process p = r.exec("mysql -p password -u user database -e 'LOAD DATA INFILE ....");

您会发现这比为CSV文件的每一行运行单独的SQL查询要快得多。