zoukankan      html  css  js  c++  java
  • 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,同一批数据,使用两种方式占用内存对比如下:

    • 非流式编程


       
      image.png
    • 流式编程


       
      image.png

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

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


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

  • 相关阅读:
    [bzoj4408][Fjoi2016]神秘数
    BZOJ1102: [POI2007]山峰和山谷Grz
    BZOJ1098: [POI2007]办公楼biu
    BZOJ1097: [POI2007]旅游景点atr
    GDOI2018 新的征程
    BZOJ2084: [Poi2010]Antisymmetry
    回文树详解
    Codeforces739E. Gosha is hunting
    一道题17
    LOJ#6002. 「网络流 24 题」最小路径覆盖
  • 原文地址:https://www.cnblogs.com/leon0/p/11382923.html
Copyright © 2011-2022 走看看