JDBC查询大数据时怎么防止内存溢出-流式查询

文章目录

        • 1.前言
        • 2.流式查询介绍
        • 3.使用流式查询
          • 3.1不开启流式查询的内存占用情况
          • 3.2开启流式查询的内存占用情况
        • 4.开启流式查询的注意点

1.前言

在使用 JDBC 查询大数据时,由于 JDBC 默认将整个结果集加载到内存中,当查询结果集过大时,很容易导致 JVM 内存溢出的问题。

解决办法通常是使用分页查询,但是分页查询越往后要遍历的行数越多,效率越低。除非能够添加索引条件,但这又提高了业务逻辑的复杂度。

2.流式查询介绍

JDBC的流式查询就是在使用ResultSet对象获取查询结果集的时候,不是把结果集一次性全部加载到内存中,而是分批次读取数据。

在jdbc客户端和mysql服务端建立tcp连接后,mysql以包的形式返回数据。在查询大数据的情况下,需要分多个包发送给客户端,而流式查询就是一次读取一个包的数据(通常情况下如此),所以查询的数据大小与MySQL一次发送的包大小息息相关。可以通过MySQL的配置max_allowed_packet设置包大小上限。

3.使用流式查询

java需要引入jdbc的依赖。

3.1不开启流式查询的内存占用情况

测试代码如下:

private static void testFetch() throws SQLException {
    Connection c = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1", "zhuzi", "123456");
    Statement s = c.createStatement();
    //查询1000w条数据
    ResultSet rs = s.executeQuery("select * from gg limit 10000000");
    while (rs.next()) {
		//执行处理数据的逻辑
    }
    //休眠100s,方便查看内存情况
    try {
        Thread.sleep(100000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    rs.close();
    s.close();
    c.close();
}

使用jconsole工具查看内存使用情况,如下图所示。

可以看到,大约占用了1.5GB的内存,并且内存曲线很平稳,这说明数据是一次性全部加载到内存中的。

在这里插入图片描述

3.2开启流式查询的内存占用情况

测试代码如下:

private static void testFetch() throws SQLException {
    Connection c = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1", "zhuzi", "123456");
    //必须设置为TYPE_FORWARD_ONLY和CONCUR_READ_ONLY 当然默认也是这两个值,可以不写
    Statement s = c.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
    //必须设置为Integer.MIN_VALUE,其他值都不会生效
    s.setFetchSize(Integer.MIN_VALUE);//-2147483648
    ResultSet rs = s.executeQuery("select * from gg limit 10000000");
    while (rs.next()){
		//执行处理数据的逻辑
    }
    try {
        Thread.sleep(100000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    rs.close();
    s.close();
    c.close();
}

内存占用情况如下:

可以看到,仅占用了几十MB内存,内存占用极大的降低了,并且内存使用在慢慢增加,这是因为数据是一批一批不断加载进来的,但前面的数据还没来得及清理。但实际上我们用完一批数据那么这批数据占用的内存就能够释放掉了。

在这里插入图片描述

4.开启流式查询的注意点

前面的测试代码中提到了,在调用Statement对象的setFetchSize方法时,传递的参数必须为-2147483648,否则不会开启流式查询。

StatementImpl类源码定义如下:

protected boolean createStreamingResultSet() {
    return this.query.getResultType() == Type.FORWARD_ONLY && this.resultSetConcurrency == 1007 && this.query.getResultFetchSize() == -2147483648;
}

该方法用于判断是否开启流式查询,可以看到,它要求ResultType为FORWARD_ONLY,ResultSetConcurrency为CONCUR_READ_ONLY,以及ResultFetchSize为-2147483648

ResultSet类中这些变量的定义如下:

//查询结果通过next方法只能向后遍历,不能使用previous方法往前遍历
//开启该选项后调用previous方法回报错:
//Operation not allowed for a result set of type ResultSet.TYPE_FORWARD_ONLY.
int TYPE_FORWARD_ONLY = 1003;

//查询结果可前后遍历,数据库数据改变不会影响结果集
int TYPE_SCROLL_INSENSITIVE = 1004;

//查询结果可前后遍历,数据库数据改变会影响结果集(测试了,好像没用,不知道怎么做)
int TYPE_SCROLL_SENSITIVE = 1005;

//结果集只能读
int CONCUR_READ_ONLY = 1007;

//结果集可以修改,并且对结果集的修改能够同步到数据库
int CONCUR_UPDATABLE = 1008;

参考博客:
Mysql中JDBC的三种查询(普通、流式、游标)详解
正确使用MySQL JDBC setFetchSize()方法解决JDBC处理大结果集

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/575543.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python与pycharm如何设置文件夹为源代码根目录

相信大家遇到过下面这种情况 当我们在当前项目下引入了其它项目的代码,这是其它项目的包的导入路径是不用于当前项目的,这样导致项目无法正常起来,但是我们又不可能一个个文件去处理,这时可以用下面的方式解决 pycharm直接设置 …

Centos 5 的yum源

背景 有使用较老的Centos 5 系统内部安装软件无法正常报错,是由于系统叫老yum源存在问题 处理方法 更换下述yum源,可以将其他repo源文件备份移动到其他目录,添加下述源后重新测试 [C5.11-base] nameCentOS-5.11 baseurlhttp://vault.c…

非对称渐开线齿轮学习笔记分享

最近有小伙伴遇到了非对称渐开线齿轮的加工问题,花了些时间学习了解一下,下面是总结的学习笔记,有兴趣的朋友可以瞅瞅: 目录: 为什么要采用非对称? 非对称有什么优点? 非对称齿形如何加工? 非对称齿轮怎么测量? 非对称齿轮建模 为什么要采用非对称? 现在的传动要求…

【SSM进阶学习系列丨整合篇】Spring+SpringMVC+MyBatis 框架配置详解

文章目录 一、环境准备1.1、创建数据库和表1.2、导入框架依赖的jar包1.3、修改Maven的编译版本1.4、完善Maven目录1.5、编写项目需要的包1.6、编写实体、Mapper、Service 二、配置MyBatis环境2.1、配置mybatis的主配置文件2.2、编写映射文件2.3、测试环境是否正确 三、配置Spri…

streamlit data_editor学习之 LLM理论内存占用量计算器

streamlit data_editor学习之 LLM理论内存占用量计算器 一.效果二.代码三.运行命令四.参考链接 根据用户设置的LLM参数,计算设备内存的占用量。以web的形式方便共享,可以插入多条记录,表格更新后,可以动态计算结果 一.效果 二.代码 import streamlit as st #1.31.1 import cv…

【八股】Spring Boot

SpringBoot是如何实现自动装配的? 首先,SpringBoot的核心注解SpringBootApplication里面包含了三个注解,SpringBootConfigurationEnableAutoConfigurationComponentScan,其中EnableAutoConfiguration是实现自动装配的注解&#x…

如何最大程度使用AWS?

随着云计算技术的不断发展,AWS已经成为众多企业的首选,为其提供了强大的基础设施和服务。那么如何最大程度地、灵活地利用AWS,成为许多企业专注的焦点。九河云作为AWS的合作伙伴,为读者们提供一些技巧和策略,帮助读者充…

UL认证防逆流多功能监测装置AGF-AE-D

安科瑞薛瑶瑶18701709087/17343930412 在单逆变器系统中,仪表直接与逆变器相连。如果您的变频器有一个内置的收入等级表(RGM;该变频器 被称为收入等级变频器),您可以在 RGM 的同一总线上连接一个外部仪表。

【React】Sigma.js框架网络图-入门篇(2)

通过《【React】Sigma.js框架网络图-入门篇》有了基本认识 由于上一篇直接给出了基本代码示例,可能看着比较复杂也不知道是啥意思; 今天从理论入手重新认识下! 一、基本认识 首先,我们先了解下基础术语: 图(Graph)&…

波高仪:数字浪高仪解析

波高仪,也被称为数字浪高仪,是一种专门用于测量波浪高度的设备。它采用低功耗微处理器、24bit高精度AD转换器和长距离通信技术,配备电容式波高传感器,具有线性好、功耗低、量精度高、传输距离远、性能稳定、抗干扰能力强等特点。 …

vue中使用echarts实现X轴动态时间(天)的折线图表

项目要求x轴以一天为间隔&#xff0c;时间是动态返回的数据&#xff0c;折线图平滑展示 实现代码如下&#xff1a; <div class"echarts-main"><v-chart ref"echarts" :options"options" /> </div>// 局部引入vue-echarts im…

Python实现线性拟合及绘图

Python实现线性拟合及绘图 当时的数字地形实验&#xff0c;使用matplotlib库绘制了一张图表表示不同地形类别在不同分辨率下的RMSE值&#xff0c;并分别拟合了一条趋势线。现在来看不足就是地形较多时&#xff0c;需要使用循环更好一点&#xff0c;不然太冗余了。 代码逻辑 …

【讯为Linux驱动笔记1】申请一个字符设备

Linux下每个设备都需要有一个专属设备号&#xff1a;主设备号 次设备号 【申请字符设备】 主设备号&#xff1a;一类驱动&#xff1a;如&#xff1a;USB驱动 次设备号&#xff1a;这类驱动下的某个设备 如&#xff1a;键盘鼠标 设备号是32位的dev_t类型的&#xff0c;高12位主…

Python对Excel两列数据进行运算

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 Python对Excel两列数据进行运算 在日常工作中&#xff0c;经常会遇到需要对Excel表格中的数…

Scala 04 —— Scala Puzzle 拓展

Scala 04 —— Scala Puzzle 拓展 文章目录 Scala 04 —— Scala Puzzle 拓展一、占位符二、模式匹配的变量和常量模式三、继承 成员声明的位置结果初始化顺序分析BMember 类BConstructor 类 四、缺省初始值与重载五、Scala的集合操作和集合类型保持一致性第一部分代码解释第二…

Python 数据可视化 boxplot

Python 数据可视化 boxplot import pandas as pd import matplotlib.pyplot as plt import numpy as np import seaborn as sns# 读取 TSV 文件 df pd.read_csv(result.tsv, sep\t)normal_df df[df["sample_name"].str.contains("normal")] tumor_df df…

【Git教程】(十五)二分法排错 — 概述及使用要求,执行过程及其实现(用二分法人工排错或自动排错),替代解决方案 ~

Git教程 二分法排错 1️⃣ 概述2️⃣ 使用要求3️⃣ 执行过程及其实现3.1 用二分法人工排错3.2 用二分法自动排错 4️⃣ 替代解决方案 在开发过程中&#xff0c;我们经常会突然遇到一个错误&#xff0c;是之前早期版本在成功通过测试时没有出现过的。这时候&#xff0c;时下较…

基于实现地图弹窗轮播功能及遇到的问题解决

基本使用 获取地图 geojson 数据 链接&#xff1a; 阿里云数据可视化平台 获取ECharts npm install echarts 或者是使用地址链接 <script src"https://registry.npmmirror.com/echarts/5.4.3/files/dist/echarts.min.js"></script> <script src…

关于螺栓的注意事项和正确操作方法——SunTorque智能扭矩系统

智能扭矩系统-智能拧紧系统-扭矩自动控制系统-SunTorque 螺栓&#xff0c;作为一种常见的紧固件&#xff0c;广泛应用于各种机械设备和结构中。在日常生活和工作中&#xff0c;我们经常需要接触到螺栓&#xff0c;因此了解螺栓的一些注意事项和正确操作方法对于确保设备的安全…