注册 | 登录 |
地方论坛门户及新闻和人才网址大全

实例讲解临时处理去重 80w 数据时夯死现象

时间:2021-07-21人气:-


这篇文章主要介绍了临时处理去重 80w 数据时夯死现象,需要的朋友可以参考下

近日,在对一张百万数据的业务表进行去重时,去重操作竟然夯住了。下面就来简单回忆一下。

1、查询业务表数据量,查看到总共有200多w条

  1. SQL>selectcount(*)fromtb_bj_banker_etl;
  2. 2552381

2、查询表内应该去掉的重复数据量,共80多w条

  1. SQL>selectcount(*)fromtb_bj_banker_etlwhere(id)in(selectidfromtb_bj_banker_etlgroupbyidhavingcount(*)>1)androwidnotin(selectmax(rowid)fromtb_bj_banker_etlgroupbyidhavingcount(*)>1);
  2. 830099

3、于是,在晚上下班前,执行了下面的语句脚本,为了去重

  1. SQL>deletefromtb_bj_banker_etlwhere(id)in(selectidfromtb_bj_banker_etlgroupbyidhavingcount(*)>1)androwidnotin(selectmax(rowid)fromtb_bj_banker_etlgroupbyidhavingcount(*)>1);
  2. SQL>commit;

4、第二天,到达现场时,发现PL/SQL Developer工具中昨天晚上执行的语句仍在执行中

首先察觉,80多w的去重数据跑了一个晚上也没跑完?这肯定是哪里出了问题?

怀疑有锁表。

于是查询是否有锁表的用户。

  1. SELECTA.OWNER,--OBJECT所属用户
  2. A.OBJECT_NAME,--OBJECT名称B.XIDUSN,
  3. B.XIDSLOT,B.XIDSQN,
  4. B.SESSION_ID,--锁表用户的sessionB.ORACLE_USERNAME,--锁表用户的Oracle用户名
  5. B.OS_USER_NAME,--锁表用户的操作系统登陆用户名B.PROCESS,
  6. B.LOCKED_MODE,C.MACHINE,--锁表用户的计算机名称
  7. C.STATUS,--锁表状态C.SERVER,
  8. C.SID,C.SERIAL#,
  9. C.PROGRAM--锁表用户所用的数据库管理工具FROM
  10. ALL_OBJECTSA,V$LOCKED_OBJECTB,
  11. SYS.GV_$SESSIONCWHERE
  12. A.OBJECT_ID=B.OBJECT_IDANDB.PROCESS=C.PROCESS
  13. ORDERBY1,2

在下面结果中可以看到,锁表的只是去重语句的发起会话,并没有其它用户造成锁表,这说明语句仍然在执行嘛?带着疑问,开始尝试解决。

1 BJHYL tb_bj_banker_ETL 15 18 9000 913 BJHYL Administrator 4036:972 3 WORKGROUPBACKDB ACTIVE DEDICATED 913 3381 plsqldev.exe

2 BJHYL tb_bj_banker_ETL 15 18 9000 913 BJHYL Administrator 4036:972 3 WORKGROUPBACKDB INACTIVE DEDICATED 649 41791 plsqldev.exe

3 BJHYL tb_bj_banker_ETL 15 18 9000 913 BJHYL Administrator 4036:972 3 WORKGROUPBACKDB INACTIVE DEDICATED 817 27777 plsqldev.exe

4 BJHYL tb_bj_banker_ETL 15 18 9000 913 BJHYL Administrator 4036:972 3 WORKGROUPBACKDB INACTIVE DEDICATED 841 1981 plsqldev.exe

5、采用分批次,解决去重夯住问题

由于直接去重无法顺利进行,于是想到了分批次去重的方法,试一下。

  1. 第一次:deletefromtb_bj_banker_etlwhere(id)in(selectidfromtb_bj_banker_etlgroupbyidhavingcount(*)>1)androwidnotin(selectmax(rowid)fromtb_bj_banker_etlgroupbyidhavingcount(*)>1)andrownum<=100000;
  2. commit;
  3. 第二次:deletefromtb_bj_banker_etlwhere(id)in(selectidfromtb_bj_banker_etlgroupbyidhavingcount(*)>1)androwidnotin(selectmax(rowid)fromtb_bj_banker_etlgroupbyidhavingcount(*)>1)andrownum<=100000;
  4. commit;
  5. 。。。。。。。。。。。。。。
  6. 。。。。。。。
  7. 第八次:deletefromtb_bj_banker_etlwhere(id)in(selectidfromtb_bj_banker_etlgroupbyidhavingcount(*)>1)androwidnotin(selectmax(rowid)fromtb_bj_banker_etlgroupbyidhavingcount(*)>1);
  8. commit;

结果:通过将80多万数据划分成以10w数据为单次进行去重操作,总共用时140多秒,完成了去重80万数据的目的。但为何直接处理出现夯死情况,有待后续跟踪分析。

以上就是临时处理去重80w数据时夯死现象的全部过程,希望可以帮到大家。


上篇:Linux下通过脚本自动备份Oracle数据库并删除指定天数...

下篇:如何使用log miner分析oracle日志