一、前言

程序访问MySQL数据库时,当查询出来的数据量特别大时,数据库驱动把加载到的数据全部加载到内存里,就有可能会导致内存溢出(OOM)。

其实在MySQL数据库中提供了流式查询,允许把符合条件的数据分批一部分一部分地加载到内存中,可以有效避免OOM;本文主要介绍如何使用流式查询并对比普通查询进行性能测试。

二、JDBC实现流式查询

使用JDBC的PreparedStatement/StatementsetFetchSize方法设置为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;}

三、性能测试

创建了一张测试表my_test进行测试,总数据量为27w条,分别使用以下4个测试用例进行测试:

  • 大数据量普通查询(27w条)
  • 大数据量流式查询(27w条)
  • 小数据量普通查询(10条)
  • 小数据量流式查询(10条)

3.1. 测试大数据量普通查询

@Testpublic void testCommonBigData() throws SQLException { String sql = "select * from my_test"; testExecute(sql, false);}

27w 数据量用时 38 秒

3.1.2. 内存占用情况

使用将近 1G 内存

3.2. 测试大数据量流式查询

@Testpublic void testStreamBigData() throws SQLException { String sql = "select * from my_test"; testExecute(sql, true);}

27w 数据量用时 37 秒

3.2.2. 内存占用情况

由于是分批获取,所以内存在30-270m波动

3.3. 测试小数据量普通查询

@Testpublic void testCommonSmallData() throws SQLException { String sql = "select * from my_test limit 100000, 10"; testExecute(sql, false);}

10 条数据量用时 1 秒

3.4. 测试小数据量流式查询

@Testpublic void testStreamSmallData() throws SQLException { String sql = "select * from my_test limit 100000, 10"; testExecute(sql, true);}

10 条数据量用时 1 秒

四、总结

MySQL 流式查询对于内存占用方面的优化还是比较明显的,但是对于查询速度的影响较小,主要用于解决大数据量查询时的内存占用多的场景。

「DEMO地址」:https://github.com/zlt2000/mysql-stream-query

更多相关文章

  1. mybatisplus的坑 insert标签insert into select无参数问题的解决
  2. python起点网月票榜字体反爬案例
  3. 《Android开发从零开始》——25.数据存储(4)
  4. Android系统配置数据库注释(settings.db)
  5. Android中不同应用间实现SharedPreferences数据共享
  6. Android(安卓)流式布局FlowLayout(搜索历史),多布局、删除、添加
  7. android图表ichartjs
  8. Android内容提供者源码
  9. android SharedPreferences

随机推荐

  1. 如何使用Android SDK开发Android应用?
  2. Android NDK开发技巧二
  3. Android中文合集 最终版
  4. Android开发的前景分析――之你为何看好A
  5. Android开发实例源代码批量下载
  6. android去除标题栏-------全屏运行AND 无
  7. Android开发规范(编码+性能+UI)
  8. android检查网络是否正常
  9. 移动设备操作系统知识点简摘又名我的期末
  10. Android 驱动开发---Android Linux 内核