使用 Java 写入 MySQL 数据库的性能低下
Low performance writing to MySQL database using Java
我的服务器有性能问题。
现在是设置:
我租了一个虚拟服务器(4 GB,2 vCores/Threads)。在此服务器上运行一个 Java 程序,该程序通过 TCP 连接到第二个服务器。一旦服务器1连接到服务器2,服务器2就开始连续发送数据(每分钟约250,000行,每行约50字节的数据)。服务器 1 然后拆分每一行并通过向 MySQL 数据库的 table 添加一行并在服务器 1 上 运行 来存储数据。好的,这就是问题所在:绝不我的服务器 1 可以跟上吗?
这些是相关的 Java 部分。
接收数据:
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);
}
}
一切都简单明了。并写入数据:
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...
}
}
那么我怎样才能提高性能呢?
1.) 一点也不,因为服务器太慢了?
2.) 使用不同的语言(例如没有口译员)会有帮助吗?
3.) 是编程草率吗?
感谢您的帮助!
拉斐尔
我也有这个问题。创建一个 SQL 查询,同时插入多行!以编程方式执行!!!
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) ..."
仅确保 SQL 查询长度不超过允许的最大长度 * 65,536*(不同数据库可能不同)。
https://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html
一条SQL语句被预编译并存储在一个PreparedStatement对象中。然后可以使用该对象多次高效地执行该语句。
每次换行时,您都创建 PreparedStatement 对象!!!取而代之的是收集多行,然后做一个插入语句!
好的,这真的归结为停止单独插入每一行。
然而,仅仅使用 YCF_L 指出的批处理语句是不够的。我还需要修改我的连接参数。没有 "rewriteBatchedStatements=true" 就没有性能提升。
DriverManager.getConnection("jdbc:mysql://localhost/"
+ database + "?user=userXY&rewriteBatchedStatements=true");
谢谢 Jan Khonski,因为你的回答也会奏效。但是,我将我的标记为正确的,因为我想列出几种方法。
我最终放弃了批处理语句,并通过隐式关闭自动提交来使用延迟的数据库更新。
实现这一点的一种方法是用 START TRANSACTION 封装一系列 INSERT 语句;并提交;
参见MySQL Documentation。
到目前为止,当数据库变大时,哪种方法运行最好,我还没有结果。
我的服务器有性能问题。
现在是设置:
我租了一个虚拟服务器(4 GB,2 vCores/Threads)。在此服务器上运行一个 Java 程序,该程序通过 TCP 连接到第二个服务器。一旦服务器1连接到服务器2,服务器2就开始连续发送数据(每分钟约250,000行,每行约50字节的数据)。服务器 1 然后拆分每一行并通过向 MySQL 数据库的 table 添加一行并在服务器 1 上 运行 来存储数据。好的,这就是问题所在:绝不我的服务器 1 可以跟上吗?
这些是相关的 Java 部分。
接收数据:
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);
}
}
一切都简单明了。并写入数据:
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...
}
}
那么我怎样才能提高性能呢?
1.) 一点也不,因为服务器太慢了?
2.) 使用不同的语言(例如没有口译员)会有帮助吗?
3.) 是编程草率吗?
感谢您的帮助! 拉斐尔
我也有这个问题。创建一个 SQL 查询,同时插入多行!以编程方式执行!!!
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) ..."
仅确保 SQL 查询长度不超过允许的最大长度 * 65,536*(不同数据库可能不同)。
https://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html 一条SQL语句被预编译并存储在一个PreparedStatement对象中。然后可以使用该对象多次高效地执行该语句。
每次换行时,您都创建 PreparedStatement 对象!!!取而代之的是收集多行,然后做一个插入语句!
好的,这真的归结为停止单独插入每一行。
然而,仅仅使用 YCF_L 指出的批处理语句是不够的。我还需要修改我的连接参数。没有 "rewriteBatchedStatements=true" 就没有性能提升。
DriverManager.getConnection("jdbc:mysql://localhost/"
+ database + "?user=userXY&rewriteBatchedStatements=true");
谢谢 Jan Khonski,因为你的回答也会奏效。但是,我将我的标记为正确的,因为我想列出几种方法。
我最终放弃了批处理语句,并通过隐式关闭自动提交来使用延迟的数据库更新。
实现这一点的一种方法是用 START TRANSACTION 封装一系列 INSERT 语句;并提交;
参见MySQL Documentation。 到目前为止,当数据库变大时,哪种方法运行最好,我还没有结果。