MySQL中流式查询使用

一、前言

MySQL 是目前使用比较广泛的关系型数据库,而从数据库里面根据条件查询数据到内存的情况想必大家在日常项目实践中都有使用。

当指定条件的数据量特别大时候一般是通过分页的方式在前端页面通过 Tag 标签一页页的加载数据到内存;但是有些情况下却不需要用户切换 Tag 标签的方式一页页的加载数据,这时候如果一下子全部把数据加载内存,就有可能会导致 OOM,虽然这时候可以通过程序控制分页查询,但是每次查询时候数据库都需要把所有符合条件的数据查询出来然后根据当前页的返回来返回指定的页,这无疑加重了 MySQL 服务器不必要的开销。

其实在 MySQL 中提供了流式查询,这允许把符合条件的数据一部分一部分的加载到内存,本 Chat 就来具体讲解如何在 MySQL中使用流式查询:

  • 使用流式查询前,我们是如何在 MySQL 中进行查询数据的,整个过程发生了什么?
  • 如何使用 JDBC 编程方式在 MySQL 中使用流式查询?

二、普通查询

image.png

  • 当我们在JVM进程里面的某一个线程里面执行数据库查询时候,其实这个请求首先会调用mysql驱动程序。
  • mysql驱动接受到请求后会向MySQL服务器发起TCP请求,服务器端根据条件查询出匹配的数据,然后通过TCP链接发送到MySQL驱动
  • MySQL驱动内则会把符合条件的数据缓存到驱动内,等服务器返回了所有符合条件的数据后,在一下子把缓存里面的数据返回给调用sql的应用程序。

所以如果查询的数据量特别大,那么mysql驱动内缓存就可能把内存撑爆造成OOM。

三、JDBC编程中MySQL流式查询

mysql客户端流式查询不会一下子把服务器端所有数据缓存起来,而是一部分一部分的把服务器端返回的数据返回给应用程序层,所以可以有效避免OOM。

JDBC编程中MYSQL流式查询例子:

public void selectData(String sqlCmd,) throws SQLException {

    validate(sqlCmd);

    Connection conn = null;
    PreparedStatement stmt = null;
    ResultSet rs = null;

    try {

        conn = petadataSource.getConnection();
        
        stmt = conn.prepareStatement(sqlCmd, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
            stmt.setFetchSize(Integer.MIN_VALUE);
            
        rs = stmt.executeQuery();

        try {
            while(rs.next()){
                try {
                    System.out.println("one:" + rs.getString(1) + "two:" + rs.getString(2) + "thrid:" + rs.getString(3));
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        } finally {
            close(stmt, rs, conn);

        }
}

可知只是prepareStatement时候改变了参数为ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,并且设置了PreparedStatement的fetchsize为Integer.MIN_VALUE。

四、最后

上面我们讲解了JDBC中流式查询使用,那么如下在Mybatis中使用那?

  • 如何在 Mybatis 中使用 MyBatisCursorItemReader 进行流式查询?
  • 如何在 Mybatis 中使用 ResultHandler 进行流式查询?
  • 什么是客户端流式查询和服务器端流式查询? 更多流式查询请单击 单击我

我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=25hh8jpv4h34s

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏SpringBoot 核心技术

第四十四章: 基于SpringBoot & AOP完成统一资源自动查询映射

4079
来自专栏.NET开发者社区

一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](八)

前言 Hi, 大家好,还是星期五,还是Rector,又在图享网准时和大家见面了。 今天给大家带来系列教程《一步一步创建ASP.NET MVC5程序[Reposi...

5026
来自专栏乐沙弥的世界

Oracle SGA 自动管理特性(sga_target参数)

    最近有网友对Oracle SGA内存自动管理特性不是很清楚,可能是由于当时翻译的 Oracle 10g SGA 的自动化管理 比较生涩,下面依旧是针对这...

933
来自专栏MasiMaro 的技术博文

windows 下进程池的操作

在Windows上创建进程是一件很容易的事,但是在管理上就不那么方便了,主要体现在下面几个方面: 1. 各个进程的地址空间是独立的,想要在进程间共享资源比较...

1383
来自专栏扎心了老铁

使用spark与MySQL进行数据交互的方法

在项目中,遇到一个场景是,需要从Hive数据仓库中拉取数据,进行过滤、裁剪或者聚合之后生成中间结果导入MySQL。 对于这样一个极其普通的离线计算场景,有多种技...

1.2K9
来自专栏企鹅号快讯

大数据入门基础系列之浅谈Hive的数据存储和元数据存储

Hive的数据存储 从表(Table)、外部表(External Table)、分区(Partition)和桶(Bucket)。 (1)Hive数据库 类似传统...

24710
来自专栏清风

原创哈希数据导出算法 原

1527
来自专栏AILearning

Apache Zeppelin 中 Cassandra CQL 解释器

Name Class Description %cassandra CassandraInterpreter 为Apac...

2789
来自专栏MySQL实战分享

【MySQL经典案例分析】关于数据行溢出由浅至深的探讨

故事的开头我们先来看一个常见的sql报错信息, 相信对于这类报错大家一定遇到过很多次了...

3166
来自专栏IT杂记

关于MySQL DNS解析探究之二:unauthenticated user

把这篇没写完的文章写完,2015年的事就不留到2016了 开启DNS解析 mysql> show variables like 'skip_name_resol...

2728

扫码关注云+社区

领取腾讯云代金券