我正在将数据库从 Java DB 复制到 MySQL。MySql中所有的表都设置正确,我写了一个复制数据库的方法。
该方法没有错误,它在大小有限的表上完美运行。但是对于大表来说太慢了。复制 7937 条记录大约需要 5 分 29 秒!由于一张表有 230 万条记录,我将不得不等待超过 26 小时......
我在 Netbeans 中运行它,我的输出在这里:(batch size = 2000)
跑: ------ 复制表币 ------ 需要复制26行 为货币执行批处理,插入最后 26 个元素 ------ 完成抄表币 ------ ------ 复制表交换 ------ 需要复制31行 执行批量交换,插入最后 31 个元素 ------ 完成拷贝表交换 ------ ------ 复制牌桌市场 ------ 需要复制82行 为市场执行批处理,插入最后 82 个元素 ------ 完成复制表市场 ------ ------ 跟单交易 ------ 2303371行需要复制 执行批量交易,插入2000个元素共复制了2000/2303371行,0% 执行批量交易,插入2000个元素共复制了4000/2303371行,0% 执行批量交易,插入2000个元素共复制了6000/2303371行,0% BUILD STOPPED(总时间:5 分 29 秒)
所以当我看到这需要比预期更长的时间时,我停止了执行。
/**
*
* @param javadb 连接到源数据库
* @param mysql 连接目标数据库
* @param orderedTables 表名按照它们被复制的顺序(所以不会发生外键约束错误)
*/
public static void copyFromJavaDBtoMySQL(Connection javadb, Connection mysql, String[] orderedTables, int batchSize){
声明 javadb_stmnt = null;
PreparedStatement mysql_stmnt = null;
尝试 {
for (int i = 0; i < orderedTables.length; i++){
//打印出一些关于正在复制哪个表以及该表包含多少行的信息。
System.out.println("------ 复制表 " + orderedTables[i] + " ------ ");
int numberRows = DataBase.executeCountQuery(orderedTables[i], null); //获取表中行的辅助方法
System.out.println(numberRows + "需要复制的行数");
int totalNumberCopied = 0;
//Get resultset from source table
String selectQuery = "select * from " + orderedTables[i];
javadb_stmnt = javadb.createStatement();
ResultSet rs_select = javadb_stmnt.executeQuery(selectQuery);
//Creating insert query for target table. Query will be 'insert into <tablename> values (?, ?, ..., ?)'
int colCount = rs_select.getMetaData().getColumnCount();
String insert_query = "insert into " + orderedTables[i] + "( ";
String valuesSubstring = "values (";
for (int j = 0; j < colCount-1; j++){
insert_query += rs_select.getMetaData().getColumnName(j+1) + ", ";
valuesSubstring += "?, ";
}
insert_query += rs_select.getMetaData().getColumnName(colCount) + ") ";
insert_query += valuesSubstring + "?)";
//Use prepared statement with batches
mysql_stmnt = mysql.prepareStatement(insert_query);
int counter = 0;
//Iterate over resultset from source table
while (rs_select.next()){
//Add batch to insert statement from the current row in result set
for (int j = 1; j <= colCount; j++){
Object obj = rs_select.getObject(j);
mysql_stmnt.setObject(j, obj);
}
mysql_stmnt.addBatch();
//If I have added enough inserts, execute the batch insert
if (++counter == batchSize){
int[] arr = mysql_stmnt.executeBatch();
//Print out some progressinformation
totalNumberCopied += arr.length;
double progress = (1.0*totalNumberCopied) / (1.0*numberRows) * 100;
DecimalFormat df = new DecimalFormat("#");
System.out.print("Executed batch for "+orderedTables[i]+", inserted " + arr.length + " elements");
System.out.println("\t Have copied a total of " + totalNumberCopied + "/" + numberRows + " rows, " + df.format(progress) + "%");
//Reset counter for batch size
counter = 0;
}
}
//Insert the last elements
int[] arr = mysql_stmnt.executeBatch();
System.out.println("Executed batch for "+orderedTables[i]+", inserted the last " + arr.length + " elements");
System.out.println("------ Finished copying table " + orderedTables[i] + " ------ \n");
}
} catch (SQLException ex) {
Logger.getLogger(DataBaseCopier.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
javadb.close();
mysql.close();
} catch (SQLException ex) {
Logger.getLogger(DataBaseCopier.class.getName()).log(Level.SEVERE, null, ex);
}
}
}