简体   繁体   English

使用Java向MySQL数据库写入性能低下

[英]Low performance writing to MySQL database using Java

I have a performance problem with my server. 我的服务器出现性能问题。

Now here is the setup: 现在这里是设置:

I have rented a virtual server (4 GB, 2 vCores/Threads). 我租了一个虚拟服务器(4 GB,2个vCores / Threads)。 On this server runs a Java program that connects to a second server via TCP. 在该服务器上运行一个Java程序,该程序通过TCP连接到第二台服务器。 Once server 1 connects to server 2, server 2 starts sending data continuously (about 250,000 lines per Minute, each line about 50 bytes of data). 一旦服务器1连接到服务器2,服务器2就开始连续发送数据(每分钟大约250,000行,每行大约50字节的数据)。 Server 1 then splits each line and stores the data by adding a row to a table of a MySQL database also running on server 1. Ok, so here is the problem: In no way can my server 1 keep up. 然后,服务器1拆分每一行,并通过将行添加到也在服务器1上运行的MySQL数据库的表中来存储数据。好的,这就是问题所在:服务器1无法跟上。

These are the relevant Java parts. 这些是相关的Java部分。

Receiving data: 接收数据:

InputStream in = socket.getInputStream();
BufferedInputStream bin = new BufferedInputStream(in);
InputStreamReader inReader = new InputStreamReader(bin, "UTF-8");
BufferedReader reader = new BufferedReader(inReader);
String line;

... something...

    while((line = reader.readLine())!=null) {
        mySqlConn.WriteReferenceData(line);
    }
}

All just straight forward. 一切都直截了当。 And writing data: 并写入数据:

public void WriteReferenceData(String line) {
    String[] data = line.split(";");
    String query = " insert into reference (field1, field2, field3, field4, field5, field6, field7, field8)" 
        + " values (?, ?, ?, ?, ?, ?, ?, ?)";
    try {
        PreparedStatement preparedStmt = conn.prepareStatement(query);
        preparedStmt.setString (1, data[0]);
        preparedStmt.setString (2, data[1]);
        preparedStmt.setString (3, data[2]);
        preparedStmt.setString (4, data[3]);
        preparedStmt.setString (5, data[4]);
        preparedStmt.setString (6, data[5]);
        preparedStmt.setString (7, data[6]);
        preparedStmt.setString (8, data[7]);
        preparedStmt.execute();
    }
    catch (Exception e) {
        ... something...
    } 
}

So how could I improve the performance? 那么如何改善性能呢?

1.) Not at all, because the server is just too slow? 1.)完全没有,因为服务器太慢了吗?

2.) Would using a different language, (eg without Interpreter) be helpful? 2.)使用其他语言(例如,不带口译员)会有所帮助吗?

3.) Is it just sloppy programming? 3.)这只是草率的编程吗?

Thanks for you help! 感谢您的帮助! Raphael 拉斐尔

Ok, it really came down to stopping inserting each row seperately. 好的,实际上是停止单独插入每一行。

However, simply using the Batch Statement as YCF_L pointed out was insufficient. 但是,仅使用批处理语句(如YCF_L所指出的)是不够的。 I also needed to modify my connection parameters as well. 我还需要修改我的连接参数。 Without "rewriteBatchedStatements=true" there was no performance gain. 如果没有“ rewriteBatchedStatements = true”,则不会提高性能。

DriverManager.getConnection("jdbc:mysql://localhost/" 
    + database + "?user=userXY&rewriteBatchedStatements=true");

Thank you Jan Khonski, as you answer would have worked, too. 谢谢扬·洪斯基(Jan Khonski),您的回答也将奏效。 However, I am marking mine as correct as I would like to list several ways of doing it. 但是,我标记我的观点是正确的,就像我想列举几种方法一样。

I ended up discarding Batch Statements and used delayed database updates by implicitly turning autocommit off. 我最终放弃了批处理语句,并通过隐式关闭自动提交功能使用了延迟的数据库更新。

One way of achieving this is to encapsulate a series of INSERT statements with START TRANSACTION; 实现此目的的一种方法是使用START TRANSACTION封装一系列INSERT语句。 and COMMIT; 和COMMIT;

See MySQL Documentation . 参见MySQL文档 So far I have no results on which method runs best when the database grows bigger. 到目前为止,当数据库变大时,我对哪种方法运行最好没有任何结果。

I had this problem too. 我也有这个问题。 Create one SQL query which inserts multiple rows at the same time! 创建一个SQL查询,该查询可同时插入多行! Do it programmatically!!! 以编程方式执行!!!

  insert into reference (field1, field2, field3, field4, field5, field6, field7, field8)" 
    + " values (v00, v01, v02, v03, v04,v05, v06, v07),
     (v10, v11, v12, v13, v14,v15, v16, v17) ..."

Only make sure than SQL query length does not exceed maximum allowed * 65,536* (it can be different for different databases). 仅确保SQL查询长度不超过允许的最大值* 65,536 *(对于不同的数据库,它可以有所不同)。

https://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html A SQL statement is precompiled and stored in a PreparedStatement object. https://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html SQL语句已预编译并存储在PreparedStatement对象中。 This object can then be used to efficiently execute this statement multiple times. 然后可以使用该对象多次有效地执行该语句。

You create PreparedStatement object each time when a new line comes!!! 每次出现新行时,您都会创建PreparedStatement对象!!! Instead collect multiple lines and then make one insert statement! 而是收集多行,然后执行一个插入语句!

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

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