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准备数据的时间比较长,我测试情况下需要一分钟才会返回结果到内存(数据量比较大),然后才能通过数据集访问数据。

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

Mybatis中使用参考:http://www.jianshu.com/p/0339c6fe8b61

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: Mysql中使用JDBC流式查询避免数据量过大导致OOM

加多

加多

研发工程师 at 阿里巴巴
加多,目前就职于阿里巴巴,对并发编程、CalssLoader,Spring等开源框架熟悉;喜爱运动,比如跑步。微信公众号:技术原始积累
加多
FavoriteLoading添加本文到我的收藏
  • Trackback are closed
  • Comments (0)
  1. No comments yet.

You must be logged in to post a comment.

return top