select id,name,balance FROM account where id >= (select a.id from account a where a.update_time >='2020-09-19' limit 100000, 1) LIMIT 10;(可以加下时间条件到外面的主查询)
SELECT acct1.id,acct1.name,acct1.balance FROM account acct1 INNERJOIN (SELECT a.id FROM account a WHERE a.update_time >='2020-09-19'ORDERBY a.update_time LIMIT 100000, 10) AS acct2 on acct1.id= acct2.id;
//查询上报总数量
Integer total = accountDAO.countAccount();
//查询上报总数量对应的SQL
<select id ='countAccount' resultType="java.lang.Integer">
seelct count(1)
from account
where create_time >='2021-01-01 00:00:00'
and type ='A'
</select>
//计算页数
int pageNo = total % pageSize == 0 ? total / pageSize : (total / pageSize + 1);
//分页查询,上报
for(int i = 0; i < pageNo; i++){
List<AcctountPO> list = accountDAO.listAccountByPage(startRow,pageSize);startRow = (pageNo-1)*pageSize;
//上报大数据
postBigData(list);
//分页查询SQL(可能存在limit深分页问题,因为account表数据量几百万)
<select id ='listAccountByPage' >
seelct *
from account
where create_time >='2021-01-01 00:00:00'
and type ='A'
limit #{startRow},#{pageSize}
</select>
实战优化方案
以上的实现方案,会存在limit深分页问题,因为account表数据量几百万。那怎么优化呢?
其实可以使用标签记录法,有些伙伴可能会有疑惑,id主键不是连续的呀,真的可以使用标签记录?
当然可以,id不是连续,我们可以通过order by让它连续嘛。优化方案如下:
//查询最小ID
String lastId = accountDAO.queryMinId();
//查询最小ID对应的SQL
<select id="queryMinId" returnType=“java.lang.String”>
select MIN(id)
from account
where create_time >='2021-01-01 00:00:00'
and type ='A'
</select>
//一页的条数
Integer pageSize = 100;
List<AcctountPO> list ;list = listAccountByPage(lastId,pageSize);
//标签记录法,记录上次查询过的Id
lastId = list.get(list,size()-1).getId();
//上报大数据
postBigData(list);
}while(CollectionUtils.isNotEmpty(list));
<select id ="listAccountByPage">
select *
from account
where create_time >='2021-01-01 00:00:00'
and id > #{lastId}
and type ='A'
order by id asc
limit #{pageSize}
</select>
复制代码