実例説明臨時処理で重さ80 wデータを消す時の突きつぶし現象


最近、百万のデータを一枚の業務表に向かって重い荷物を運びに行った時、重い操作に行きました。簡単に思い出してみます。
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_bakerETL 15 18 9000 913 BJHYL Administrator 4036:972 WORKGROUTP\BACKDB ACTIVE DEDICATED 913 3381 plsqldev.exe
2 BJHYL tb_bj_bakerETL 15 18 9000 913 BJHYL Administrator 4036:972 WORKGROUP\BACKDB INACTIVE DEDICATED 649 41791 plsqldev.exe
3 BJHYL tb_bj_bakerETL 15 18 9000 913 BJHYL Administrator 4036:972 WORKGROUP\BACKDB INACTIVE DEDICATED 817 plsqldev.exe
4 BJHYL tb_bj_bakerETL 15 18 9000 913 BJHYL Administrator 4036:972 WORKGROUP\BACKDB INACTIVE DEDICATED 841 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万以上のデータを10 wのデータに分割して、単独で重い操作を行うことによって、全部で140秒以上を使って、80万のデータを重くする目的を達成しました。しかし、なぜ直接処理したのかについては、突き止めの状況が出てきました。フォローアップの分析が必要です。
以上は仮処分で80 wのデータを落とした時に死亡現象を起こす全過程です。