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

所属分类: 数据库 / oracle 阅读数: 713
收藏 0 赞 0 分享

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

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

SQL> select count(*) from tb_bj_banker_etl;

2552381

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

SQL> select count(*) from tb_bj_banker_etl where (id) in (select id from tb_bj_banker_etl group by id having count(*)>1) and rowid not in(select max(rowid) from tb_bj_banker_etl group by id having count(*)>1);

830099

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

SQL> delete from tb_bj_banker_etl where(id) in (select id from tb_bj_banker_etl group by id having count(*)>1) and rowid not in(select max(rowid) from tb_bj_banker_etl group by id having count(*)>1);

SQL> commit;

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

首先察觉,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_OBJECTS A, 
 V$LOCKED_OBJECT B, 
 SYS.GV_$SESSION C 
WHERE 
 A.OBJECT_ID = B.OBJECT_ID 
 AND B.PROCESS = C.PROCESS 
ORDER BY 1,2 

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

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

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

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

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

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

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

第一次: 
delete from tb_bj_banker_etl where(id) in (select id from tb_bj_banker_etl group by id having count(*)>1) and rowid not in(select max(rowid) from tb_bj_banker_etl group by id having count(*)>1) and rownum<=100000; 
commit; 
 
第二次: 
delete from tb_bj_banker_etl where(id) in (select id from tb_bj_banker_etl group by id having count(*)>1) and rowid not in(select max(rowid) from tb_bj_banker_etl group by id having count(*)>1) and rownum<=100000; 
commit; 
 
。。。。。。。 
。。。。。。。 
。。。。。。。 
 
第八次: 
delete from tb_bj_banker_etl where(id) in (select id from tb_bj_banker_etl group by id having count(*)>1) and rowid not in(select max(rowid) from tb_bj_banker_etl group by id having count(*)>1); 
commit; 

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

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

更多精彩内容其他人还在看

VS2015连接Oracle数据库的详细步骤

这篇文章主要介绍了VS2015连接Oracle数据库的详细步骤,需要的朋友可以参考下
收藏 0 赞 0 分享

常用的Oracle doc命令(收藏)

这篇文章主要介绍了常用的Oracle doc命令(收藏)的相关资料,非常不错,具有参考借鉴价值,需要的朋友参考下吧
收藏 0 赞 0 分享

ORACLE SQL语句优化技术要点解析

这篇文章主要介绍了ORACLE SQL语句优化技术的相关内容,小编觉得挺不错的,在这里分享给大家,需要的朋友可以参考下。
收藏 0 赞 0 分享

ORACLE多条件统计查询的简单方法

这篇文章主要介绍了ORACLE多条件统计查询的简单方法,具有一定参考价值。这里给大家分享下,希望对大家有所帮助。
收藏 0 赞 0 分享

ORACLE批量导入图片到BLOB字段代码示例

这篇文章主要介绍了ORACLE批量导入图片到BLOB字段代码示例,此代码示例是文章作者的项目源码,具有一定参考价值,需要的朋友可以了解下。
收藏 0 赞 0 分享

PLSQL Developer登录的默认密码介绍

这篇文章主要介绍了PLSQL Developer登录的默认密码介绍,具有一定参考价值,需要的朋友可以了解下。
收藏 0 赞 0 分享

Oracle数据行拆分多行方法示例

oracle数据库使用过程中,怎样将一行或者多行数据分割成需要的多行数据,本文我们就来看看具体方法,需要的朋友可以参考。
收藏 0 赞 0 分享

Oracle表空间不足的两种解决办法

这篇文章主要介绍了Oracle表空间不足的两种解决办法,需要的朋友可以参考下
收藏 0 赞 0 分享

巧妙解决Oracle NClob读写问题(经验分享)

下面小编就为大家带来一篇巧妙解决Oracle NClob读写问题(经验分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

oracle执行update语句时卡住问题分析及解决办法

这篇文章主要介绍了oracle执行update语句时卡住问题分析及解决办法,涉及记录锁等相关知识,具有一定参考价值,需要的朋友可以了解。
收藏 0 赞 0 分享
查看更多