大数据量查询容易OOM?试试MySQL流式查询

一、前言
程序访问 MySQL 数据库时,当查询出来的数据量特别大时,数据库驱动把加载到的数据全部加载到内存里,就有可能会导致内存溢出(OOM)。
其实在 MySQL 数据库中提供了流式查询,允许把符合条件的数据分批一部分一部分地加载到内存中,可以有效避免OOM;本文主要介绍如何使用流式查询并对比普通查询进行性能测试。
二、JDBC实现流式查询
使用JDBC的 PreparedStatement/Statement 的 setFetchSize 方法设置为 Integer.MIN_VALUE 或者使用方法 Statement.enableStreamingResults() 可以实现流式查询,在执行 ResultSet.next() 方法时,会通过数据库连接一条一条的返回,这样也不会大量占用客户端的内存。
public int execute(String sql, boolean isStreamQuery) throws SQLException {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
int count = 0;
try {
//获取数据库连接
conn = getConnection();
if (isStreamQuery) {
//设置流式查询参数
stmt = conn.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);
} else {
//普通查询
stmt = conn.prepareStatement(sql);
}
//执行查询获取结果
rs = stmt.executeQuery();
//遍历结果
while(rs.next()){
System.out.println(rs.getString(1));
count++;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(stmt, rs, conn);
}
return count;
}
PS:上面的例子中通过参数
isStreamQuery来切换流式查询与普通查询,用于下面做测试对比。
三、性能测试
创建了一张测试表 my_test 进行测试,总数据量为 27w 条,分别使用以下4个测试用例进行测试:
- 大数据量普通查询(27w条)
- 大数据量流式查询(27w条)
- 小数据量普通查询(10条)
- 小数据量流式查询(10条)
3.1. 测试大数据量普通查询
@Test
public void testCommonBigData() throws SQLException {
String sql = "select * from my_test";
testExecute(sql, false);
}
3.1.1. 查询耗时
27w 数据量用时 38 秒

3.1.2. 内存占用情况
使用将近 1G 内存

3.2. 测试大数据量流式查询
@Test
public void testStreamBigData() throws SQLException {
String sql = "select * from my_test";
testExecute(sql, true);
}
3.2.1. 查询耗时
27w 数据量用时 37 秒

3.2.2. 内存占用情况
由于是分批获取,所以内存在30-270m波动

3.3. 测试小数据量普通查询
@Test
public void testCommonSmallData() throws SQLException {
String sql = "select * from my_test limit 100000, 10";
testExecute(sql, false);
}
3.3.1. 查询耗时
10 条数据量用时 1 秒

3.4. 测试小数据量流式查询
@Test
public void testStreamSmallData() throws SQLException {
String sql = "select * from my_test limit 100000, 10";
testExecute(sql, true);
}
3.4.1. 查询耗时
10 条数据量用时 1 秒

四、总结
MySQL 流式查询对于内存占用方面的优化还是比较明显的,但是对于查询速度的影响较小,主要用于解决大数据量查询时的内存占用多的场景。
DEMO地址:https://github.com/zlt2000/mysql-stream-query
扫码关注有惊喜!

大数据量查询容易OOM?试试MySQL流式查询的更多相关文章
- DB2大数据量优化查询解决方案
利用DB2表分区的功能对大数据量的表进行分区,可以优化查询. 表分区介绍: 表分区是一种数据组织方案,它根据一列或多列中的值把表数据划分为多个称为数据分区 的存储对象. (我觉得表分区就类似于Wind ...
- Mysql中使用JDBC流式查询避免数据量过大导致OOM
一.前言 java 中MySQL JDBC 封装了流式查询操作,通过设置几个参数,就可以避免一次返回数据过大导致 OOM. 二.如何使用 2.1 之前查询 public void selectData ...
- mysql处理大数据量的查询速度究竟有多快和能优化到什么程度
mysql处理大数据量的查询速度究竟有多快和能优化到什么程度 深圳-ftx(1433725026) 18:10:49 mysql有没有排名函数啊 横瓜(601069289) 18:13:06 无 ...
- MySQL大数据量分页查询
mysql大数据量使用limit分页,随着页码的增大,查询效率越低下. 测试实验 1. 直接用limit start, count分页语句, 也是我程序中用的方法: select * from p ...
- 【1】MySQL大数据量分页查询方法及其优化
---方法1: 直接使用数据库提供的SQL语句---语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N---适应场景: 适用于数据量较少的情况(元组百/千 ...
- MySQL大数据量分页查询方法及其优化
MySQL大数据量分页查询方法及其优化 ---方法1: 直接使用数据库提供的SQL语句---语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N---适 ...
- MySQL分页查询大数据量优化方法
方法1: 直接使用数据库提供的SQL语句 语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N适应场景: 适用于数据量较少的情况(元组百/千级)原因/缺点: ...
- mysql的大数据量的查询
mysql的大数据量查询分页应该用where 条件进行分页,limit 100000,100,mysql先查询100100数据量,查询完以后,将 这些100000数据量屏蔽去掉,用100的量,但是如果 ...
- 提高MYSQL大数据量查询的速度
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...
随机推荐
- HTTP协议数据包
HTTP数据包 简介:由w3c制定的一种网络应用层协议,定义了浏览器与web服务器之间通信时所使用的数据格式. 0x00 数据包格式 1.请求行:请求类型/请求资源路径.协议的版本和类型 2.请求头: ...
- 自学linux——21. NFS服务器的搭建
NFS服务器的搭建 1.NFS的认识 NFS(Network File System即网络文件系统)服务最大的功能就是可以透过网络,让不同的机器.不同的操作系统.可以彼此分享文件,可以将远程 Linu ...
- Leetcode学习笔记(4)
题目1 ID121 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润. 注意你不能在买入股 ...
- ripple Failed to load resource: the server responded with a status of 404 (Not Found)
在VS2015中使用Cordova + typescript开发中,遇到个问题. 在javascript console 中提示: Failed to load resource: the serve ...
- 个人作业三——ATM管理系统
一 作业信息 博客班级 https://edu.cnblogs.com/campus/ahgc/AHPU-se-JSJ18/ 作业要求 https://edu.cnblogs.com/campus/a ...
- Robot Framework+adb框架自动化测试Android设备案例⑸——L1层测试用例
一.L1层测试用例 1.初始化.robot *** Settings *** Resource ../L2层关键字.robot *** Test Cases *** 切换EMMC模式 [Tags] A ...
- Oracle 迁移数据库到 mysql
一. oracle导出.sql文件(Navicat Premiu 11.0.8 无法实现oracle到mysql的数据传输亲测有效) exp username/pass@数据局地址ip:1521/ ...
- Spring AOP的理解(通俗易懂)。
转载 原文链接:http://www.verydemo.com/demo_c143_i20837.html 这种在运行时,动态地将代码切入到类的指定方法.指定位置上的编程思想就是面向切面的编程. 1. ...
- 写一个为await自动加上catch的loader逐渐了解AST以及babel
为什么要写这个loader 我们在日常开发中经常用到async await去请求接口,解决异步.可async await语法的缺点就是若await后的Promise抛出错误不能捕获,整段代码区就会卡住 ...
- 【Go语言绘图】图片的旋转
在上一篇中,我们了解了gg库的基本使用,包括调整大小.调整圆形参数.设置颜色.保存图片.加载图片和裁剪.这一篇我们来学习一下图片的旋转. 加载图片 首先,我们先来一张黄图. func TestRota ...