実現したいこと
・該当UPDATE文の処理時間短縮
前提・発生している問題
OracleDBを使用し、一時表へデータをINSERT・一時表内でUPDATE・一時表からSELECTを行うプロシージャを作成しました。
SQLDevelopperで実行した際、更新対象データ件数が8000件程度であれば下記のUPDATE文1つに20分以上かかります(1時間かかる場合もあり、その時々によって変わる)。
UPDATE文はプロシージャ内で複数記述していますが、処理時間を要するものは** DENSE_RANK() OVER(~~) **を利用している以下のようなUPDATE文の場合に限られるようで、それ以外のUPDATE文は1秒以内で完了します。
UPDATE文の大幅な処理速度の低下について考えられる原因・解決策・調査方法をご教示ください。
該当のソースコード
Oracle
1 UPDATE 2 TMP_TABLE T 3 SET 4 T.NUM = ( 5 SELECT 6 WK_T.SORT_NO 7 FROM 8 ( 9 SELECT DISTINCT 10 COLUMN1 11 , COLUMN2 12 , COLUMN3 13 , COLUMN4 14 , SORT_COLUMN 15 , DENSE_RANK() OVER(ORDER BY SORT_COLUMN) AS SORT_NO 16 FROM 17 TMP_TABLE 18 )WK_T 19 WHERE 20 T.COLUMN1 = WK_T.COLUMN1 21 AND T.COLUMN2 = WK_T.COLUMN2 22 AND T.COLUMN3 = WK_T.COLUMN3 23 AND T.COLUMN4 = WK_T.COLUMN4 24 AND T.SORT_COLUMN = WK_T.SORT_COLUMN 25 ) 26 ;
試したこと
更新対象データ件数を8000件から6000件に減らすと、同じUPDATE文が1秒以内で実行完了することを確認しました。
補足情報
・ACTIVEなSQLのコストを確認すると233059397でした。(そこからコストは変化しませんでした)
・また、以下のSQLでセッション情報を確認しました。
select a.INST_ID , a.SID , a.TYPE , a.ACTION , a.COMMAND , c.COMMAND_NAME , a.STATUS , a.LAST_CALL_ET -- 今の状態になってからの経過時間 , trunc((sysdate - a.SQL_EXEC_START) * 24 * 60 * 60, 2) as "秒" --実行し続けている時間 , a.WAIT_CLASS -- 待機イベントクラス , a.EVENT ----- 一時セグメントを利用しているか , u.TABLESPACE , u.SEGTYPE -- 一時セグメントの種別 , u.BLOCKS -- 割り当てられたブロック数 --PGA情報 , p.PGA_USED_MEM --現在使用中のPGA , p.PGA_ALLOC_MEM --現在割り当てられているPGAメモリ , p.PGA_FREEABLE_MEM --解放できる割当済みPGAメモリ , p.PGA_MAX_MEM --割り当てられた最大PGAメモリ from gv$SESSION a left outer join gv$process p on a.INST_ID = p.INST_ID and a.PADDR = p.ADDR left outer join gv$transaction r on a.SADDR = r.SES_ADDR and a.INST_ID = r.INST_ID left outer join gV$TEMPSEG_USAGE u on a.SADDR = u.SESSION_ADDR and a.SERIAL# = u.SESSION_NUM and a.INST_ID = u.INST_ID left outer join v$sqlcommand c on a.COMMAND = c.COMMAND_TYPE where 1 = 1 and a.TYPE = 'USER' and a.status = 'ACTIVE' order by a.INST_ID , a.STATUS , a.SQL_EXEC_START
・使用している一時表の構造ですが、キーは無しでNUMBER型の項目が10個あるだけです。
・SORT_COLUMNでインデックスを作成しましたが効果は全くありませんでした。
当方、プログラミング初学者の為解決に必要な情報が分かりません。不足している情報があればご指摘いただきたいです。
