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

  • 相关阅读:
    C#中KeyDown和KeyPress区别
    c#快捷键设置和text输入限制
    问题总结
    c#串口编程和单片机通信重大发现
    c#类似单片机的8bit或运算
    c#中将默认常量(32bit)转换为8bit
    我的秋季个人阅读计划
    学期总结
    阅读笔记《软件秘籍》03
    阅读笔记--09
  • 原文地址:https://www.cnblogs.com/leon0/p/11382923.html
Copyright © 2011-2022 走看看