二十八、全域性臨時表用於多delete操作的SQL優化
阿新 • • 發佈:2018-12-10
全域性臨時表用於多delete操作的SQL優化
某日,某某生產系統忽然日誌暴增,回滾段也暴增,系統IO壓力也增大…
經過診斷分析排查後發現,原來是系統昨晚新上的程式模組裡出現類似delete from t_mid 的簡單刪除語句居然在短短時間內被執行了幾十萬次,和相關人員確認後暫停了該程式。
研究程式碼邏輯發現該t_mid表其實為一張中間表,程式的運算中間臨時結果先存在這裡,運算結束,就可以清除了。
哦,這樣的需求,真需要這樣不停的去delete嗎?刪除的開銷很大且會佔用大量的回滾段和產生大量日誌,能否不要刪除呢?且看下面全域性
臨時表的例子
1、基於SESSION的全域性臨時表
基於SESSION的全域性臨時表(退出session該表記錄就會自動清空)
drop table ljb_tmp_session; create global temporary table ljb_tmp_session on commit preserve rows as select * from dba_objects where 1=2; --基於session的臨時表 select table_name,temporary,duration from user_tables where table_name='LJB_TMP_SESSION';
2、基於事務的全域性臨時表
基於事務的全域性臨時表(commit提交後,不等退出session,在該表記錄就會自動清空)
drop table ljb_tmp_transaction; create global temporary table ljb_tmp_transaction on commit delete rows as select * from dba_objects where 1=2; --基於事務的臨時表 select table_name, temporary, DURATION from user_tables where table_name='LJB_TMP_TRANSACTION';
3、測試sql
--向兩張表插入資料
insert all
into ljb_tmp_transaction
into ljb_tmp_session
select * from dba_objects;
--查詢
select session_cnt,transaction_cnt from (select count(*) session_cnt from ljb_tmp_session),
(select count(*) transaction_cnt from ljb_tmp_transaction);
--提交
commit;
--查詢
select session_cnt,transaction_cnt from (select count(*) session_cnt from ljb_tmp_session),
(select count(*) transaction_cnt from ljb_tmp_transaction);
--斷開連線 重連線
disconnect
connect ljb/ljb
--查詢
select session_cnt,transaction_cnt from (select count(*) session_cnt from ljb_tmp_session),
(select count(*) transaction_cnt from ljb_tmp_transaction);