1. 程式人生 > >Mysql中使用JDBC流式查詢避免資料量過大導致OOM

Mysql中使用JDBC流式查詢避免資料量過大導致OOM

一、前言

java 中MySQL JDBC 封裝了流式查詢操作,通過設定幾個引數,就可以避免一次返回資料過大導致 OOM。

二、如何使用

2.1 之前查詢

public void selectData(String sqlCmd) throws SQLException {

    validate(sqlCmd);

    Connection conn = null;
    PreparedStatement stmt = null;
    ResultSet rs = null;    try {


        conn = petadataSource.getConnection();
        stmt = conn.prepareStatement(sqlCmd);
        rs = stmt.executeQuery();        try
{            while(rs.next()){                try {                    System.out.println("one:" + rs.getString(1) + "two:" + rs.getString(2) + "thrid:" + rs.getString(3));                } catch (SQLException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }        } catch
(SQLException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        } finally {            close(stmt, rs, conn);        } }

2.2 現在流式查詢

public void selectData(String sqlCmd,) throws SQLException {

    validate(sqlCmd);

    Connection conn = null
;    PreparedStatement stmt = null;    ResultSet rs = null;    try {        conn = petadataSource.getConnection();        stmt = conn.prepareStatement(sqlCmd, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);            stmt.setFetchSize(Integer.MIN_VALUE);        rs = stmt.executeQuery();        try {            while(rs.next()){                try {                    System.out.println("one:" + rs.getString(1) + "two:" + rs.getString(2) + "thrid:" + rs.getString(3));                } catch (SQLException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }        } catch (SQLException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        } finally {            close(stmt, rs, conn);        } }

可知只是prepareStatement時候改變了引數,並且設定了PreparedStatement的fetchsize為Integer.MIN_VALUE。

三、 結果對比

對於同一個sqlCmd,同一批資料,使用兩種方式佔用記憶體對比如下:

  • 非流式程式設計
  • 流式程式設計

另外非流式方式由於是把符合條件的資料一下子全部加在到記憶體,並且由於資料量比較大,mysql準備資料的時間比較長,我測試情況下需要一分鐘才會返回結果到記憶體(資料量比較大),然後才能通過資料集訪問資料。

而流式方式是每次返回一個記錄到記憶體,所以佔用記憶體開銷比較小,並且呼叫後會馬上可以訪問資料集的資料。


加多

加多

高階 Java 攻城獅 at 阿里巴巴加多,目前就職於阿里巴巴,熱衷併發程式設計、ClassLoader,Spring等開源框架,分散式RPC框架dubbo,springcloud等;愛好音樂,運動。微信公眾號:技術原始積累。知識星球賬號:技術原始積累