use*_*650 4 java sql sybase jdbc
我正在尝试从sybase服务器读取表,处理行,并将结果输出到另一个表.(以下是我的代码)
代码检索表非常快,并且处理速度相同(在30秒内得到它发送的部分).但是当我运行执行批处理时,它会在那里停留20分钟(fyi,我有一个表,我正在测试8400行).
有没有更有效的方法来做到这一点?我可以接受如何收到或发送查询(我可以创建一个新表,更新表等) - 我只是不知道为什么这么慢(我确定数据<1 MB和我确定它不需要SQL服务器20分钟来解析8400行).有任何想法吗?
注意:这对我来说真的很糟糕的原因是我必须解析一个1.2 MM行的表(我正在使用的这个表是一个8400行的测试表)
Connection conn = DriverManager.getConnection(conString, user, pass);
String sql = "SELECT id,dateid,attr from user.fromtable";
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(sql);
String sqlOut = "INSERT INTO user.mytabletest (id,attr,date,estEndtime) values (?,?,?,?)";
PreparedStatement ps = conn.prepareStatement(sqlOut);
int i=1;
while(rs.next())
{
int date = rs.getInt("dateid");
String attr = rs.getString("attr");
String id = rs.getString("id");
Time tt = getTime(date,attr);
Timestamp ts = new Timestamp(tt.getTime());
ps.setString(1, id);
ps.setString(2, attr);
ps.setInt(3, date);
ps.setTimestamp(4, ts);
ps.addBatch();
if(i % 10000 == 0)
{
System.out.println(i);
ps.executeBatch();
conn.commit();
ps.clearBatch();
}
i++;
}
System.out.println("sending "+(new Date()));
int[] results = ps.executeBatch();
System.out.println("committing "+(new Date()));
conn.commit();
System.out.println("done "+(new Date()));
Run Code Online (Sandbox Code Playgroud)
要有效地使用批处理,您应关闭AutoCommit选项并在执行批处理后将其打开(或者使用connection.commit()方法)
connection.setAutoCommit(false);
while(rs.next())
{
.....
ps.addBatch();
}
int[] results = ps.executeBatch();
connection.setAutoCommit(true);
Run Code Online (Sandbox Code Playgroud)
小智 9
将?rewriteBatchedStatements=true添加到 JDBC url 的末尾。它会给你一个严重的性能改进。请注意,这是特定于 MySql 的,不会对任何其他 JDBC 驱动程序产生任何影响。
例如:jdbc:mysql://server:3306/db_name?rewriteBatchedStatements=true
它使我的表现提高了 15 倍以上
我遇到了同样的问题,终于弄清楚了,虽然我也无法在任何地方找到正确的解释.
答案是.executeBatch()不应使用简单的无条件插入物.批处理模式正在做的是使许多单独的"插入表x ..."语句,这就是它运行缓慢的原因.但是,如果insert语句更复杂,可能的条件会不同地影响每一行,那么它可能需要单独的insert语句,批处理执行实际上是有用的.
什么有用的示例,尝试以下创建单个insert语句作为PreparedStatement(但与Statement对象需要相同的概念),并解决运行缓慢的问题:
public boolean addSetOfRecords(String tableName, Set<MyObject> objects) {
StringBuffer sql = new StringBuffer("INSERT INTO " + tableName + " VALUES (?,?,?,?)");
for(int i=1;i<objects.size();i++) {
sql.append(",(?,?,?,?)");
}
try {
PreparedStatement p = db.getConnection().prepareStatement(sql.toString());
int i = 1;
for(MyObject obj : objects) {
p.setString(i++, obj.getValue());
p.setString(i++, obj.getType());
p.setString(i++, obj.getId());
p.setDate(i++, new Date(obj.getRecordDate().getTime()));
}
p.execute();
p.close();
return true;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
23039 次 |
| 最近记录: |