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

news2024/12/23 22:33:02

文章目录

        • 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处理大结果集

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【项目】YOLOv8/YOLOv5/YOLOv9半监督ssod火灾烟雾检测(YOLOv8_ssod)

假期闲来无事找到一份火灾烟雾数据集,自己又补充标注了一些,通过论文检索发现现在的火灾检测工作主要局限于对新场景的泛化性不够强,所以想着用半监督,扩充数据集的方法解决这个问题,所以本文结合使用现在检测精度较高…

Canal入门使用

说明:canal [kə’nl],译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费(官方介绍)。一言以蔽之,Canal是一款实现数据同步的组件。可以实现数据库之间、数…

网络相关知识总结

1、网口设置 网口设置IP,即操作/etc/sysconfig/network-scripts路径下的ifcfg-xx文件 主要参数详解: DEVICE:网口名 ONBOOT:表示启动系统时是否激活网卡,yes为激活,no不激活 HWADDR:mac值 DEFROUTE://默认路由设置…

[C++基础学习]----01-C++数据类型详解

前言 C是一种静态类型的编程语言,它提供了丰富的数据类型来存储和操作数据。这些数据类型为C程序员提供了丰富的选择,可以根据具体需求来选择最合适的类型来存储和操作数据。下面详细解释一些常见的C数据类型,包括其原理和使用方法&#xff1…

ADOP带您科普什么是光纤网卡,它跟普通网卡有什么区别?

光纤网卡,也称为网络适配器或网络接口卡(NIC),是一种用于将计算机和服务器等设备连接到数据网络的硬件设备。它通常装有一个或多个端口,可以通过这些端口连接不同类型的网络线缆,如RJ45接口的网络跳线或SFP…

云贝餐饮连锁V2-2.9.9源码

云贝餐饮连锁V2独立版、版本更新至2.9.9,小程序、公众号版本,全插件,公众号小程序端,独立版; 带商家端,修复收银台、排队点餐、堂食点餐;最新版更新 搭建环境教程: 系统环境:CentO…

Wi-Fi HaLow:重塑物联网的未来

Wi-Fi HaLow:引领物联网连接的革命 数字时代的蓬勃发展正在引发一场深刻的变革,物联网已经融入到我们的日常生活和工作中,成为不可或缺的一部分。随着新一代Wi-Fi技术一Wi-Fi HaLow的崭露头角,有望在2024年及未来,重新…

stm32f4单片机强制类型转换为float程序跑飞问题

如题,在一个数据解析函数中使用了*(float *)&data[offset],其中data为uint8类型指针,指向的value地址为 可以看到地址0x20013A31非对齐,最终在执行VLDR指令时导致跑飞 VLDR需要使用对齐访问 跑飞后查看SCB寄存器发现确实是非…

磁盘未格式化,数据恢复大揭秘

一、磁盘未格式化现象概述 在日常使用电脑的过程中,我们有时会遇到磁盘未格式化的提示,这意味着我们的磁盘突然间变得不可识别,所有的数据和文件都似乎消失了。这种情况常常发生在外接硬盘、U盘等存储设备上,给我们的工作和生活带…

LC 142. 环形链表 II

142. 环形链表 II 给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评…

C++ ─── 隐式类型转换、static成员、友元、内部类

目录 1. explicit关键字 2. static成员 2.1 概念 2.2 特性 3. 友元 3.1 友元函数 3.2 友元类 4. 内部类 5. 再次理解类和对象 1. explicit关键字 构造函数不仅可以构造与初始化对象,对于接收单个参数的构造函数,还具有类型转换的作用。接收单个…

基因组组装:NextDenovo2 使用大全

简介 NextDenovo 是一种针对长序列读取(包括CLR和ONT技术)的新型基因组组装工具。它采取了一种“先校正错误再进行组装”的方法,这与canu工具类似,但对于PacBio HiFi读取数据则无需进行校正。相较于其他工具,NextDenov…

使用 Vitepress 构建博客并部署到 github 平台

前言 最近写了好多篇 Chrome 浏览器插件相关的文章,有十几二十篇,就想着构建个博客,用来放置相应的文章。 正好前段时间看到 VitePress 1.0.0 发布了,而且是用 markdown 写文章,正好写插件文章的时候文章都是 md 格式…

达梦数据查询语句不带模式名称,报错无效的表或视图名[某某表]

[执行语句1]: select * from sys_config 执行失败(语句1) -2106: 第2 行附近出现错误: 无效的表或视图名[SYS_CONFIG]1条语句执行失败 解决方案: 保证模式名和用户名一致,而且你当前登录的用户要和模式名一致 把用户换成一样的,查询就可以不 …

如何利用 GPT 自我提高写作能力

GPT革命:如何用AI技术重新定义写作 介绍 在我们的数字时代,了解自我提高写作的必要性至关重要。 随着 GPT 的兴起,我们正在见证书写的变革时代。 这篇扩展文章深入探讨了 GPT 如何显着提高写作技能。 拥抱未来: 人工智能时代的写…

HarmonyOS 应用开发——入门

首先当然是华为的官方文档了,要认真学习: https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/start-overview-0000001478061421-V2 不想花时间看,可以看我下面总结的干货,哈哈 第一个问题:stage架构和fa架构的区…

Linux下的常用基本指令

基本指令 前言ls 指令语法功能常用选项举例注意要点关于拼接关于 -a关于文件ls与/的联用ls与根目录ls与任意文件夹ls与常用选项与路径 ls -d与ls -ldls与ll pwd命令语法功能常用选项注意要点window与Linux文件路径的区别家目录 cd 指令语法功能举例注意要点cd路径.. .相对路径与…

【中级软件设计师】上午题12-软件工程(1):软件工程模型、敏捷方法、软件需求、系统设计

上午题12-软件工程(1) 1 软件过程1.1 CMM 能力成熟度模型1.1 CMMI (建议直接看思维导图) 2 软件过程模型2.1 瀑布模型2.2 增量模型2.3 演化模型2.3.1 原型模型2.3.2 螺旋模型 2.5 喷泉模型 3 统一过程(UP)模型4 敏捷方…

Kafka报错ERROR Exiting Kafka due to fatal exception during startup

报错: ERROR Exiting Kafka due to fatal exception during startup. (kafka.Kafka$) kafka.common.InconsistentClusterIdException: The Cluster ID FSzSO50oTLCRhRnRylihcg doesnt match stored clusterId Some(0oSLohwtQZWbIi73YUMs8g) in meta.properties. Th…

zabbix监控Tongweb7企业版(by lqw+sy)

此贴参考zabbix通过jmx监控Tongweb7企业版(by lqw),是在此帖子的基础和同事整理的文档基础上重新部署验证的优化版,使用的是centos7。 优点: 1.不需要通过jmx配置进行监控。(jmx配置需要修改tongweb的配置…