Java 在一个事务中在mysql中存储50000+条记录的最佳实践是什么

Java 在一个事务中在mysql中存储50000+条记录的最佳实践是什么,java,mysql,load-data-infile,Java,Mysql,Load Data Infile,输入集:数千个>10000个csv文件,每个文件包含>50000个条目。 输出:将这些数据存储在mysql数据库中 采取的办法: 读取每个文件并将数据存储到数据库中。下面是同样的代码片段。请说明此方法是否可行 PreparedStatement pstmt2 = null; try { pstmt1 = con.prepareStatement(sqlQuery); result = pstmt1.executeUpdate(); con.setAutoCommit(false); s

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

采取的办法: 读取每个文件并将数据存储到数据库中。下面是同样的代码片段。请说明此方法是否可行

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

我以前在类似的情况下使用过加载数据填充

LOAD DATA INFILE语句将文本文件中的行读取到 以非常高的速度移动桌子。加载数据填充是对 选择进入外文件。见第14.2.9.1节,“选择……进入 语法”。要将数据从表写入文件,请使用选择。。。进入 输出文件。要将文件读回表中,请使用“加载数据填充”。这个 FIELDS和LINES子句的语法对于这两种语言都是相同的 声明。这两个子句都是可选的,但字段必须位于行之前 如果两者都指定了

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

将数据infle'/tmp/test.txt'加载到表test IGNORE 1行中


正如@Ridrigo已经指出的,加载数据填充是一条可行之路。实际上根本不需要Java

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

您还可以使用Java代码在包含CSV的文件夹中进行迭代,然后为CSV执行系统命令

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

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

我会尝试批量导出以转储或导入以全部插入。我们要澄清术语吗?在sql world dump中,dump是指从数据库中导出的数据,可以是一组sql查询、csv或所有者格式。从转储或数据库中获取数据称为导入或加载。现在,如果你能澄清你的问题…我最近处理了一个类似的问题,在我的情况下,数据是600000+。我的解决方案是使用多线程和阻塞队列来导入数据。然而,多线程实际上并没有提高性能,它只是减少了响应时间。如果你真的想使它更快,考虑并行解决方案。但是50000太小,无法并行,其复杂性远远超过其好处。因此,我建议您坚持使用带有批量插入的单线程。@e4c5-感谢您的澄清。我修改了标题。目标是读取csv文件,并将数据存储到数据库中。这些csv文件格式是自定义的。它有一些带有一些设备详细信息的初始行,之后,列名及其各自的值将继续。可以忽略那些初始行吗?用忽略行编辑,希望有帮助。对您的详细描述非常有帮助。