実例説明臨時処理で重さ80 wデータを消す時の突きつぶし現象
最近、百万のデータを一枚の業務表に向かって重い荷物を運びに行った時、重い操作に行きました。簡単に思い出してみます。
1、業務表のデータ量を調べて、全部で200以上のw条があることを確認します。
まず気づきました。80数wの重いデータは一晩走っても走りきれませんでした。これはどこで間違いないですか?
ロックの疑いがある。
すると、ロックテーブルがあるかどうかを調べます。
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、バッチを採用して、リピング問題を解決する。
直接行くと重いのでうまくいかないので、ロット別に重い方法を考えて試してみました。
以上は仮処分で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のデータを落とした時に死亡現象を起こす全過程です。