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

  • 相关阅读:
    ubuntu用apt-get安装memcache
    Vagrant error: Your VM has become inaccessible.
    PHP数据类型转换
    vim 树形目录插件NERDTree安装及简单用法
    mysql 导入sql文件,source命令
    linux:vi 替换命令
    svn更改分支名字,move命令
    Subversion命令汇总
    不解压直接查看tar包内容
    ls按时间排序输出文件列表
  • 原文地址:https://www.cnblogs.com/leon0/p/11382923.html
Copyright © 2011-2022 走看看