`

大数据的批量更新方法

阅读更多
大数据量的批量更新方法
1. 先说我遇到的难题,数据库用户表中有2400万条数据,而我需要更新所有用户的信息,前提我不能用update table_user set xxx='?',xxa='?';全表更新 因为公司有规定一次提交的事物不能超过50W,显然这里已经超过了50W达到2400W的事物数据(全表更新数据特大的时候需要执行相当长的时间),那么我将怎么更新呢?

2. 现在来说说我用什么方法去批量更新吧!思路:首先查询满足条件的数据量是多少(我的是2400万),然后决定每1万做一页,每一页由一个线程负责执行(项目规定最多同时只有30个线程跑,其余2370个线程在等待,这是个很好的控制,不然服务器受不了会挂的);这样执行速度比全表更新还要快很多,我测试过更新2400万数据只要30分钟,而全表更新最快要60分钟,慢的时候更新不出来。


3. 第二步中显然我有意忽略了几个重点部分
  • 查询数据量很简单,直接count一下全表
  • 记住我的文章标题,我是批量更新,且看我真实sql:
  • select t1.sysId from (select t.rowid as sysId,rownum as num from (select rowid from taf_user where status=#status# order by rowid)t)t1 where mod(t1.num,#pageSize#)=0 or t1.num=1 or t1.num=#recordSum#
    其中有三个参数,status是属于自己的业务条件这里不介绍,第二个pageSize就是你准备一个线程一次更新多少数据(10000),第二个参数就是满足条件最后一笔的数据的行位置(也就是count出来的数据量,我的为24000000),这个查询会返回一个rowid分段(每10000为一段,看mod就能知道,其次还有num=1,num=24000000目的是保留第一个rowid与最后一个rowid,因为我要拿这两个的rowid做开始与结束,sql中有排序这是保证rowid顺序的)的集合,试想下这个rowid集合索引0与1这个区段刚好是1~10000行的数据,下个线程处理时从集合索引1与2取得rowidMin、rowidMax这个区段是10000~20000的数据,那么每个线程产生时给他一个编号告诉他处理哪块数据即可,这样拿rowid批量更新一段(10000)数据岂不飞快
  • 上面没有提到我的update语句,有两个一个是更新第一段时是>=#rowidMin#与<=#rowidMax#,更新第二段时是>#rowidMin#与<=#rowidMax#这样是避免重复更新,这里贴出来:
  • update taf_user t set xxx='?',xxa='?' where t.rowid>=#rowidMin# and t.rowid<=#rowidMax# and status='?'

    update taf_user t set xxx='?',xxa='?' where t.rowid>#rowidMin# and t.rowid<=#rowidMax# and status='?'
0
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics