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

  • 相关阅读:
    “XXXXX” is damaged and can’t be opened. You should move it to the Trash 解决方案
    深入浅出 eBPF 安全项目 Tracee
    Unity3d开发的知名大型游戏案例
    Unity 3D 拥有强大的编辑界面
    Unity 3D物理引擎详解
    Unity 3D图形用户界面及常用控件
    Unity 3D的视图与相应的基础操作方法
    Unity Technologies 公司开发的三维游戏制作引擎——Unity 3D
    重学计算机
    windows cmd用户操作,添加,设备管理员组,允许修改密码
  • 原文地址:https://www.cnblogs.com/leon0/p/11382923.html
Copyright © 2011-2022 走看看