实例讲解临时处理去重 80w 数据时夯死现象
近日,在对一张百万数据的业务表进行去重时,去重操作竟然夯住了。下面就来简单回忆一下。
1、查询业务表数据量,查看到总共有200多w条
SQL>selectcount(*)fromtb_bj_banker_etl; 2552381
2、查询表内应该去掉的重复数据量,共80多w条
SQL>selectcount(*)fromtb_bj_banker_etlwhere(id)in(selectidfromtb_bj_banker_etlgroupbyidhavingcount(*)>1)androwidnotin(selectmax(rowid)fromtb_bj_banker_etlgroupbyidhavingcount(*)>1); 830099
3、于是,在晚上下班前,执行了下面的语句脚本,为了去重
SQL>deletefromtb_bj_banker_etlwhere(id)in(selectidfromtb_bj_banker_etlgroupbyidhavingcount(*)>1)androwidnotin(selectmax(rowid)fromtb_bj_banker_etlgroupbyidhavingcount(*)>1); SQL>commit;
4、第二天,到达现场时,发现PL/SQLDeveloper工具中昨天晚上执行的语句仍在执行中
首先察觉,80多w的去重数据跑了一个晚上也没跑完?这肯定是哪里出了问题?
怀疑有锁表。
于是查询是否有锁表的用户。
SELECT A.OWNER,--OBJECT所属用户 A.OBJECT_NAME,--OBJECT名称 B.XIDUSN, B.XIDSLOT, B.XIDSQN, B.SESSION_ID,--锁表用户的session B.ORACLE_USERNAME,--锁表用户的Oracle用户名 B.OS_USER_NAME,--锁表用户的操作系统登陆用户名 B.PROCESS, B.LOCKED_MODE, C.MACHINE,--锁表用户的计算机名称 C.STATUS,--锁表状态 C.SERVER, C.SID, C.SERIAL#, C.PROGRAM--锁表用户所用的数据库管理工具 FROM ALL_OBJECTSA, V$LOCKED_OBJECTB, SYS.GV_$SESSIONC WHERE A.OBJECT_ID=B.OBJECT_ID ANDB.PROCESS=C.PROCESS ORDERBY1,2
在下面结果中可以看到,锁表的只是去重语句的发起会话,并没有其它用户造成锁表,这说明语句仍然在执行嘛?带着疑问,开始尝试解决。
1BJHYLtb_bj_banker_ETL15189000913BJHYLAdministrator4036:9723WORKGROUP\BACKDBACTIVEDEDICATED9133381plsqldev.exe
2BJHYLtb_bj_banker_ETL15189000913BJHYLAdministrator4036:9723WORKGROUP\BACKDBINACTIVEDEDICATED64941791plsqldev.exe
3BJHYLtb_bj_banker_ETL15189000913BJHYLAdministrator4036:9723WORKGROUP\BACKDBINACTIVEDEDICATED81727777plsqldev.exe
4BJHYLtb_bj_banker_ETL15189000913BJHYLAdministrator4036:9723WORKGROUP\BACKDBINACTIVEDEDICATED8411981plsqldev.exe
5、采用分批次,解决去重夯住问题
由于直接去重无法顺利进行,于是想到了分批次去重的方法,试一下。
第一次: deletefromtb_bj_banker_etlwhere(id)in(selectidfromtb_bj_banker_etlgroupbyidhavingcount(*)>1)androwidnotin(selectmax(rowid)fromtb_bj_banker_etlgroupbyidhavingcount(*)>1)andrownum<=100000; commit; 第二次: deletefromtb_bj_banker_etlwhere(id)in(selectidfromtb_bj_banker_etlgroupbyidhavingcount(*)>1)androwidnotin(selectmax(rowid)fromtb_bj_banker_etlgroupbyidhavingcount(*)>1)andrownum<=100000; commit; 。。。。。。。 。。。。。。。 。。。。。。。 第八次: deletefromtb_bj_banker_etlwhere(id)in(selectidfromtb_bj_banker_etlgroupbyidhavingcount(*)>1)androwidnotin(selectmax(rowid)fromtb_bj_banker_etlgroupbyidhavingcount(*)>1); commit;
结果:通过将80多万数据划分成以10w数据为单次进行去重操作,总共用时140多秒,完成了去重80万数据的目的。但为何直接处理出现夯死情况,有待后续跟踪分析。
以上就是临时处理去重80w数据时夯死现象的全部过程,希望可以帮到大家。