1. 程式人生 > >二十八、全域性臨時表用於多delete操作的SQL優化

二十八、全域性臨時表用於多delete操作的SQL優化

          全域性臨時表用於多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);