我有一個MySQL
數據庫位於服務器x和另一個在服務器y。插入從select查詢中檢索到的MySQL結果集?
我試圖讓從表中的記錄叫testx這是位於服務器X和INSERT
他們到一個表名爲暴躁。所以我所做的是執行SELECT
聲明並將其存儲到resultset
。然後我試圖在resultset
while
循環內迭代INSERT
語句。這是我的示例代碼:
private static void cloneTableAndAlter() throws ClassNotFoundException, SQLException, InstantiationException, IllegalAccessException, InterruptedException {
Connection connForSource = getConnectionForSource();
Connection connForTarget = getConnectionForTarget();
if (connForSource != null && connForTarget != null) {
try {
Statement st = connForSource.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
java.sql.ResultSet.CONCUR_READ_ONLY);
String selectStatement = "SELECT field1, field2 FROM dbx.testx where time between ('2016-09-01 00:00:00') and ('2016-09-03 23:59:59');";
String insertStatement = "INSERT INTO testy(" + "field1," + "field2)" +
"VALUES(?,?) " +
"ON DUPLICATE KEY UPDATE field1 = VALUES(field1);"; <----field1 is a unique key but not primary
st.setFetchSize(Integer.MIN_VALUE);
ResultSet resultSetForSelect = st.executeQuery(selectStatement);
PreparedStatement preparedStatement = connForTarget.prepareStatement(insertStatement);
int count = 0;
while (resultSetForSelect.next()) {
++count;
TableDetails tableDetails = setTableDetails(resultSetForSelect); <--- i'm getting the value from the resultset and setting it to my DTO class.
getTableDetails(preparedStatement, tableDetails); <--- setting the values back during the insert from the DTO
preparedStatement.executeUpdate();
System.out.println(count + "rows affected");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
注意:源表(testx)擁有超過一百萬條記錄。
我能夠做插入,但我覺得插入是有點慢,我得到45-50插入每秒。我要去哪裏?
有什麼辦法可以優化這個操作並增加插入,或者這是插入大型數據集的本質嗎?
任何幫助,不勝感激。
我想通過測量什麼需要時間啓動。它是讀取還是寫入,還是兩者兼而有之。如果讀取速度很慢,也許你只需要在時間欄上有一個索引。如果寫入速度較慢,則可以使用批處理來發送批次插入,而不是一次只進行一次插入。如果兩者都存在,也許網絡就是問題所在。 –
謝謝@JBNizet,注意。 「只需要時間列上的索引」是什麼意思? – Kulasangar
您的qquery將在testx表中查找rwo值之間的時間行。如果您沒有在該時間列上定義數據庫索引,那麼MySQL將進行全表掃描以查找要查找的行。如果您定義了索引,則可以使用該索引更快地查找行。 –