MySQL mybatis使用游标查询获取数据集

本文探讨了从MySQL数据库高效导出百万级数据的方法,对比了一次性查询和使用服务器游标的性能,揭示了fetchSize在MySQL中的实际作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

从数据集中查询100W条 数据并生成到文件中

环境:Mysql5.7 innodb

显然不能一次性数据集查询到本地

那么有两种做法

1、用limit 分页查询

在一个事务中多次分页查询 然后讲结果集交给其他处理线程写文件;使用可重复读事务隔离级别 能够保证即使在处理过程中其他事务修改插入删除了满足条件的记录 多次分页查询的数据是确定的,且并不会阻塞这些CUD操作

2、使用服务端游标;

mybatis mapper文件:

<select id="selectForwardOnly" parameterType="xxx.TblUconlTransFlowHis" resultMap="BaseResultMap" fetchSize="-2147483648">
接口声明:void selectForwardOnly(TblUconlTransFlowHis record,
                       ResultHandler<TblUconlTransFlowHis> handler);

接口实现:
tblUconlTransFlowHisMapper.selectForwardOnly(transFlowHisKey, new ResultHandler<TblUconlTransFlowHis>() {
    @Override
    public void handleResult(ResultContext<? extends TblUconlTransFlowHis> resultContext) {
        //写文件
        //logger.debug();
        logger.debug(JSONObject.toJSONString(resultContext.getResultObject()));
        //list.add(resultContext.getResultObject());
    }
})

fetchSize设为-2147483648(Integer.MIN_VALUE) 一开始我希望或许fetchSize能够自己指定一次从服务器端获取的数据量;发现修改fetchSize的值并没有差别;结果是MYSQL并不支持自定义fetchSize 看网上说其他大型数据库(oracl db2)是支持的;mysql使用服务器端游标只能一条一条取数据。

提一句题外话:如果接口方法参数没有声明回调函数ResultHandler ,声明fetchSize也是没有任何作用的 依然会返回完整结果集。

使用1W条数据集实验

一次性查询整个结果集到客户端花费30S,然后写文件3S

使用游标2S后就开始有数据返回并写文件然后一共花费30S;跟预期也是符合的,当然可以数据积攒到一定量再用其他线程写,性能会再有所提升。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值