mysql鏈接數據庫的時候,須要從表中拖數據,若是數據量過大會致使服務內存溢出。會提示java.lang.OutOfMemoryError: Java heap space錯誤。html
使用setFetchSize(1000)指定獲取接口大小java
ps=conn.con.prepareStatement("select * from bigTable");
ps.setFetchSize(1000);
複製代碼
事實上,這種指定的方法是沒有任何效果的,服務器仍是會一次性取出全部數據放在客戶端內存中,此時setFetchSize參數不起做用,當一條SQL返回數據量較大時可能會出現JVM OOM。mysql
使用setFetchSize(Integer.MIN_VALUE)sql
ps = connection.prepareStatement("select * from bigTable",
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
複製代碼
此時客戶端會逐個從服務器段獲取數據數據庫
事實上,setFetchSize(1000)也能夠生效的,須要使用useCursorFetch=truebash
conn = DriverManager.getConnection("jdbc:mysql://localhost/?useCursorFetch=true", "user", "s3cr3t");
stmt = conn.createStatement();
stmt.setFetchSize(100);
rs = stmt.executeQuery("SELECT * FROM your_table_here");
複製代碼
摘自:https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-implementation-notes.html
服務器
經過指定limit/offset,分頁讀取,這裏再也不詳細敘述。ui
可是該方法會有一個潛在的問題,如讀取重複數據、髒數據,除非在讀取以前LOCK表,讀取完成後 UNLOCK 表 看到網上的解決方案, 能夠經過建立一個臨時表解決spa
CREATE TEMPORARY TABLE AS SELECT..., and read with LIMIT/OFFSET
複製代碼
事實上也並非很好,最好仍是經過這種遊標取數據。code