Mybatis plus 大数据量查询慢问题

  大数据量操作一般用在数据迁移,数据导出,批量处理数据
  在实际工作中当中,查询数据过大,我们使用分页查询的方式一页一页的将数据放到内存处理。但有些情况不需要分页的方式查询数据或者分很大一页查询数据时,如果一下子将数据全部加载出来到内存中,很可能会发生OOM(内存溢出),而且查询会很慢,大量的时间和内存耗费在把数据库查询的结果封装成我们想要的对象。
问题:系统需要从mysql数据库里读取100w数据进行处理,需要怎么做?

  • 常规查询:一次性读取100w数据到jvm内存中,或者分页读取
  • 流式查询:建立长连接,利用服务端游标,每次读取一条加载到jvm内存(多次获取,一次一行)
  • 游标查询:和流式一样,通过fetchSize参数,控制一次读取多少条数据(多次获取,一次多行)

常规查询

@Mapper
public interface BigDataSearchMapper extends BaseMapper<BigDataSearchEntity> {@Select("select * from big_data ${ew.customSqlSegment}")Page<BigDataSearchEntity> pageList(@Param("page) Page<BigDataSearchEntity> page, @Param(Constants.WRAPPER) QueryWrapper<BIgDataSearchEntity> queryWrapper);
}

  如果不考虑limit深分页优化的情况下,或者等上几十分钟或几小时

流式查询

  Mybatis提供一个叫org.apache.ibatis.cursor.Cursor的接口类用于流式查询,这个接口继承了java.io.Closeable和java.lang.Iterable接口,所以Cursor是可关闭,可遍历的。Cursor提供了三个方法:

  • isOpen():用于在取数据之前判断Cursor对象是否是打开状态,只有当打开时Cursor才能取数据
  • isConsumed():用于判断查询结果是否全部取完
  • getCurrentIndex():返回已经获取了多少条数据

使用流式查询,则要保持对产生结果集的语句所引用的表的并发访问,因为其查询会独占连接

@Mapper
public interface BigDataSearchMapper extends BaseMapper<BigDataSearchEntity> {//  一次获取,一次一行@Select("select * from big_data ${ew.customSqlSegment} ")@Options(resultSetType = ResultSetType.FORWARD_ONLY, fetchSize = 100000)@ResultType(BigDataSearchEntity.class)void listData(@Param(Constants.WRAPPER) QueryWrapper<BigDataSearchEntity> queryWrapper, ResultHandler<BigDataSearchEntity> handler);
}

  如果有一个很大的查询结果需要遍历处理,又不想一次性将结果集装入客户端内存,就可以考虑使用流式查询;分库分表场景下,单个表的查询结果集虽然不大,但如果某个查询跨了多个库多个表,又要做结果集的合并、排序等动作,依然有可能撑爆内存;详细研究sharding-sphere的代码不难发现,除了group by 与order by字段不一样之外,其它的场景都非常适合使用流式查询,可以最大限度的降低对客户端内存的消耗。

游标查询

  对大量数据进行处理时,可以采用游标方式进行数据查询处理。不仅可以节省内存的消耗,而且还不需要一次性取出所有数据,可以进行逐条处理或逐条取出部分批量处理。一次查询指定 fetchSize 的数据,直到把数据全部处理完。

Mybatis 的处理加了两个注解:@Options和@ResultType

@Mapper
public interface BigDataSearchMapper extends BaseMapper<BigDataSearchEntity> {// 多次获取,一次多行@Select("select * from big_data ${ew.customSqlSegment} ")@Options(resultSetType = ResultSetType.FORWARD_ONLY, fetchSize = 1000000)Page<BigDataSearchEntity> pageList(@Param("page") Page<BigDataSearchEntity> page, @Param(Constants.WRAPPER) QueryWrapper<BigDataSearchEntity> queryWrapper);
}

  @Options

  • ResultSet.FORWORD_ONLY:结果集的游标只能向下滚动
  • ResultSet.SCROLL_INSENSITIVE:结果集的游标可以上下移动,当数据库变化时,当前结果集不变
  • ResultSet.SCROLL_SENSITIVE:返回可滚动的结果集,当数据库变化时,当前结果集同步改变
  • fetchSize:每次获取量

  @ResultType

  • @ResultType(BigDataSearchEntity.class):转换成返回实体类型(注意:返回类型必须为 void ,因为查询的结果在 ResultHandler 里处理数据,所以这个 hander 也是必须的,可以使用 lambda 实现一个依次处理逻辑)

  Oracle 是从服务器一次取出 fetch size 条记录放在客户端,客户端处理完成一个批次后再向服务器取下一个批次,直到所有数据处理完成。
  MySQL 是在执行 ResultSet.next() 方法时,会通过数据库连接一条一条的返回。flush buffer 的过程是阻塞式的,如果网络中发生了拥塞,send buffer 被填满,会导致 buffer 一直 flush 不出去,那 MySQL 的处理线程会阻塞,从而避免数据把客户端内存撑爆。
  另外要切记每次处理完一批结果要记得释放存储每批数据的临时容器。

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

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

相关文章

SpringMVC学习笔记

先赞后看&#xff0c;养成习惯&#xff01;&#xff01;&#xff01;❤️ ❤️ ❤️ 资源收集不易&#xff0c;如果喜欢可以关注我哦&#xff01; ​如果本篇内容对你有所启发&#xff0c;欢迎访问我的个人博客了解更多内容&#xff1a;链接地址 是什么 Spring MVC是Spring框架…

C++面向对象(OOP)编程-友元(友元函数和友元类)

本文主要介绍面向对象编程的友元的使用&#xff0c;以及友元的特性和分类&#xff0c;提供C代码。 1 为什么引进友元 面向对象编程&#xff08;OOP&#xff09;的三大特性中的封装&#xff0c;是通过类实现对数据的隐藏和封装。一般定义类的成员变量为私有成员&#xff0c;成员…

模拟目录管理 - 华为OD统一考试(C卷)

OD统一考试(C卷) 分值: 200分 题解: Java / Python / C++ 题目描述 实现一个模拟目录管理功能的软件,输入一个命令序列,输出最后一条命令运行结果。 支持命令: 1)创建目录命令: mkdir 目录名称,如mkdir abc为在当前目录创建abc目录,如果已存在同名目录则不执行任何操作…

0x12 队列

0x12 队列 队列是一种“先进先出”的线性数据结构。一般来说&#xff0c;元素从右端进入队列&#xff0c;从左端离开队列。于是我们称队列的左端为队头&#xff0c;右端为队尾。 队列还有许多变体。例如两端都能插入或者取出元素的双端队列&#xff08;C S T L STL STL d e…

CentOS7安装 Docker Compose

docker系列 CentOS7安装 Docker Compose docker系列前言1、下载 Docker Compose2、 授权执行权限3、添加软链接4、验证安装 前言 下面的操作是在centos7中完成的。这里安装的是2.23.3版本的docker-compose。 1、下载 Docker Compose 确保你具有 curl 工具&#xff0c;然后使用…

python基于http的网络通信和网站端口暴露;Python网络编程之HTTP协议的python应用

一、HTTP协议概述 HTTP&#xff08;Hypertext Transfer Protocol&#xff09;即超文本传输协议&#xff0c;是Web应用程序使用的协议&#xff0c;在Web浏览器和Web服务器之间传递HTML页面和数据。HTTP是基于TCP/IP协议来传输数据的&#xff0c;是一种无状态的协议。 关键特点…

每个开发人员都想使用的编程语言

在任何时候&#xff0c;一些编程语言都会把大量的开发人员变成热情的布道者&#xff0c;试图说服世界其他地方的人相信它的伟大。 当热起来的时候&#xff0c;这种语言可能会成为行业标准&#xff0c;但其他时候&#xff0c;这种受欢迎程度就会消失。 在这个故事中&#xff0…

模拟I2C通信

test.c #include "iic.h"extern void printf(const char *fmt, ...); /** 函数名 &#xff1a; delay_us* 函数功能&#xff1a;延时函数* 函数参数&#xff1a;无* 函数返回值&#xff1a;无* */ void delay_us(void) {unsigned int i 2000;while (i--); } void d…

【JVM从入门到实战】(五)类加载器

一、什么是类加载器 类加载器&#xff08;ClassLoader&#xff09;是Java虚拟机提供给应用程序去实现获取类和接口字节码数据的技术。 类加载器只参与加载过程中的字节码获取并加载到内存这一部分。 二、jdk8及之前的版本 类加载器分为三类&#xff1a; 启动类加载器-加载Ja…

golang游戏服务器 - tgf系列课程07

数据管理 使用数据管理工具,对玩家数据进行自动化的缓存管理.需求描述 用户登录成功之后,我们需要根据用户的账号,创建用户的数据,并且将数据存放到mysql和redis中.之后我们通过接口,修改玩家的昵称,然后重新登录.观察数据是否准确准备工作 在开始服务器的代码编程之前,我们…

Linux cp命令教程:如何复制文件和目录(附案例详解和注意事项)

Linux cp命令介绍 cp命令在Linux中用于复制文件或目录。它的全称是copy&#xff0c;意为复制。使用cp命令&#xff0c;你可以将文件或目录从一个位置复制到另一个位置。 Linux cp命令适用的Linux版本 cp命令在所有主流的Linux发行版中都是可用的&#xff0c;包括但不限于Ubu…

绩效面谈为什么失败?

绩效面谈是整个绩效管理过程中的核心环节&#xff0c;是绩效反馈环节的重要手段之一。绩效面谈工作的成功与否直接关系到绩效管理体系能否良性运行&#xff0c;绩效改善的目标能否真正实现。对于许多已经导入绩效管理理念&#xff0c;并初步建立起绩效管理体系的企业来说&#…

pip install默认安装路径

pip install默认安装路径 当使用pip工具安装Python包时&#xff0c;默认情况下&#xff0c;包会被安装到Python的site-packages目录中。这个目录的路径取决于你的操作系统和Python的安装方式。 在Windows操作系统上&#xff0c;pip默认安装路径通常是C:\PythonXX\Lib\site-…

express 下搞一个 websocket 长连接

安装模块 npm i express npm i express-ws 新建文件app.js 先安排源码 监听端口 7777 var express require(express) var app express() require(express-ws)(app)var port 7777 var clientObject {} app.ws(/, (client, req) > {// 连接var key req.socket.re…

预测性维护对制造企业设备管理的作用

制造企业设备管理和维护对于生产效率和成本控制至关重要。然而&#xff0c;传统的维护方法往往无法准确预测设备故障&#xff0c;导致生产中断和高额维修费用。为了应对这一挑战&#xff0c;越来越多的制造企业开始采用预测性维护技术。 预测性维护是通过传感器数据、机器学习和…

计算机网络——习题——书上原题

目录 第一章 1. 填空题 第二章 1. 填空题 第三章 1. 填空题 2.选择题 第四章 1. 填空题 第五章 第六章 1. 填空题 第一章 1. 填空题 &#xff08;1&#xff09;计算机网络的主要功能包括 资源共享、数据通信、分布式处理、提高计算机的可靠性和集中管理 。 &…

上海亚商投顾:沪指再度失守3000点 北向资金净卖出近百亿

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 三大指数昨日集体调整&#xff0c;尾盘均跌超1%&#xff0c;北证50则逆势拉升涨超3%。医药股逆势走强&#xf…

Node.js模块化的基本概念和分类及使用方法

1.模块概念 模块&#xff1a;指解决一个复杂问题的时候&#xff0c;自顶向下逐层把系统划分成若干模块的过程。对于整个系统来讲&#xff0c;模块是可以组合、分解和更换的单元。 在编辑领域中的模块&#xff0c;就是遵守固定的规则&#xff0c;把一个大文件拆成独立并且相互…

devops相关面试题

1、发布10 NPM包,熟悉NRM、NVM。 1、谈谈你参与发布的NPM包,它们解决了什么问题,有什么特点? NPM: 是 Node.js 默认的包管理工具 NRM&#xff1a;是 Node.js 源管理工具 NVM&#xff1a;Node.js 版本管理工具 我参与发布的NPM包为mk-form,它通过配置生成和验证复杂表单,简化…

网络编程及相关概念

网络 概念&#xff1a;两台或多台设备通过一定物理设备连接起来构成了网络 根据网络的覆盖范围不同&#xff0c;对网络进行分类&#xff1a; 局域网&#xff1a;覆盖范围最小&#xff0c;仅仅覆盖一片小区域。 城域网&#xff1a;覆盖范围较大&#xff0c;可以覆盖一个城市。…