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中使用JDBC流式查询避免数据量过大导致OOM image.png
  • 流式编程


      Mysql中使用JDBC流式查询避免数据量过大导致OOM image.png

另外非流式方式由于是把符合条件的数据一下子全部加在到内存,并且由于数据量比较大,需要mysql处理的时间比较长,我测试情况下需要一分钟才会返回结果到内存(数据量比较大),然后才能通过数据集返回数据。

而流式方式是每次返回一个记录到内存,所以占用内存开销比较小,并且调用后会马上可以访问数据集的数据。


--------------
转自
链接:https://www.jianshu.com/p/c1e6eeb71c74

上一篇:JAVA OOM总结


下一篇:Java 如何有效地避免OOM:善于利用软引用和弱引用