批量更新数据的方案

批量更新数据首先要分页查询出来,那么有一个问题,如何去查?
能想到的最简单的方式,sql是这样的:

#先查出总数,分页
select count(*) from t where status = 2;
#过程如下
select id,name from t where status = 2 order by id limit 0, 100;
select id,name from t where status = 2 order by id limit 100, 100;

使用上面的语句,

首先就是巨慢,因为是查全量然后分页的。

其次,两次分页查询之间没有关联,如果有某些数据的状态,从status=1到了status=2,那么会导致一个问题:
由于页数已经确定(count不变),实际count + n了,那么本来在最后一页的数据,可能查不到了。

最好是这样:
每次查询都把上一批查询的数据的最大id作为查询条件带入,初始设置maxId(查出最早的id,不能用0,否则第一次就会扫描整个主键索引树), 每次分页查询后更新maxId,这样解决了上面的问题1和问题2,如下:

select id,name from t where id >= maxId and status = 2 order by id limit 100;

不过这样会有一个问题3:如果业务比较活跃,这张表一直有新数据插入,那么岂不是永远停不下来?
问题3这样的情况,数据页大概率在内存中,那么insert语句只写写到当前数据页中,不用进入change buffer,会写redo log,然后直接把内存中的数据返回,所以是有可能数据一直停不下来的(个人臆想了)。

后续:发现用maxId的方式,同样不太现实,如果id >= maxId 的数据多了,又回到了开始没有maxId的状态了,再次成为了慢查询语句,

解决方案是 再加一个 id <= maxId + 100000, 控制住扫表的行数,果然耗时降了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值