解析JDBC使用遊標查詢MySQL
使用jdbc查詢MySQL資料庫,如果使用遊標或者流式查詢的話,則可以有效解決OOM的問題,否則MySQL驅動就會把資料集全部查詢出來載入到記憶體裡面,這樣在大資料的情況下會OOM的
不同的查詢方式 ResultsetRows 的實現是不一樣的!!!
流式查詢【每次只取一條】
流式查詢的條件是
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * from dwd_data_gen", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
// 每批拉取的資料量
preparedStatement.setFetchSize(Integer.MIN_VALUE);
程式碼
connection.setAutoCommit(false);
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * from dwd_data_gen", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
// 每批拉取的資料量
preparedStatement.setFetchSize(Integer.MIN_VALUE);
# 流式查詢的時候,preparedStatement.executeQuery()並不會把資料取過來,而是呼叫resultSet.next()的時候 從服務端取一條資料過來。該方式不會出現OOM,因為每次都是隻取一條資料
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
i++;
}
非流式查詢【一次性全部查出來】
流式查詢的條件不滿足的時候就會在preparedStatement.executeQuery()的時候 把所有資料查出來
resultSet.next()只是從上面查出來的結果裡面做判斷而已,不會再從資料庫取資料了
遊標查詢【每次取fetchSize條】
遊標查詢的條件是
jdbc的url裡面加上useCursorFetch=true的引數
connection.setAutoCommit(false);
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * from dwd_data_gen", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
// 每批拉取的資料量
preparedStatement.setFetchSize(1024);