Oralce-清除数据的两种思路
生活随笔
收集整理的這篇文章主要介紹了
Oralce-清除数据的两种思路
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 數據量很大
- 數據量較少
- 配置Job ,定時執行
- 定期進行表分析
數據量很大
思路: 關聯的表數據量都很大,獲取一次數據時間較長,可以考慮將數據一次性撈出來放到臨時表中,只執行一次耗時取數據的查詢,放到臨時表中,然后通過游標獲取臨時表中的數據,去對應的表中刪除。 同時考慮到業務高峰期,job執行盡量避開業務高峰期。
Warning: 第一次清理數據量比較大的時候,可以通過創建臨時表的方式,待第一次清理完成后,后續過期數據數據量小的情況下,可以采用【數據量較少】這種方法加上JOB以及表分析來開展。
create or replace procedure Proc_Clean_Inventory_Data authid current_user isv_card_number voucher_card.card_number%type;v_goods_type_id gm_goods_inst.goods_type_id%type;v_goods_stat gm_goods_inst.goods_state%type;v_inventory_clean_record_num number(3);v_temp_inventory_index_num number(3);v_createRecordTableSql varchar2(4000);v_createTempTableIndexSql varchar2(4000);v_dropTableSql varchar2(4000);v_getDataSql varchar2(4000);--- create table temp_inventory_4_delete(card_number varchar2(60));-- cusrosr card_number collection cursor cur_card_numbers is select card_number from TEMP_INVENTORY_4_DELETE;begin-- set value v_goods_type_id :='V';v_goods_stat :='C';-- create temp table v_getDataSql := 'create table TEMP_INVENTORY_4_DELETE as select card_number from voucher_card vcwhere vc.card_number in(select goods_snfrom gm_goods_instwhere GOODS_TYPE_ID = '||chr(39)||v_goods_type_id||chr(39)||'and GOODS_STATE = '||chr(39)||v_goods_stat||chr(39)||'and state_date < sysdate - 50)' ; v_dropTableSql := 'drop table TEMP_INVENTORY_4_DELETE'; v_createTempTableIndexSql := 'create index IDX_CARD_NUMBER on TEMP_INVENTORY_4_DELETE (CARD_NUMBER)'; v_createRecordTableSql :='create table inventory_clear_record(card_number VARCHAR2(60),create_time DATE)'; -- check exists or not select count(1) into v_inventory_clean_record_num from user_tables ut where ut.TABLE_NAME = 'INVENTORY_CLEAR_RECORD';-- create inventory_clear_record for onceif v_inventory_clean_record_num = 0 then execute immediate v_createRecordTableSql ;end if ; -- drop TEMP_INVENTORY_4_DELETE then recreate execute immediate v_dropTableSql ;execute immediate v_getDataSql ;-- check exists or not select count(1) into v_temp_inventory_index_num from user_indexes ui where ui.index_name = 'IDX_CARD_NUMBER';-- create index for TEMP_INVENTORY_4_DELETEif v_temp_inventory_index_num = 0 then execute immediate v_createTempTableIndexSql ;end if ; /******Clean expired Data in voucher_card And gm_goods_inst******/--open cur_card_numbers,execute the cursor define sqlopen cur_card_numbers;--begin to looploop-- fetch one record into v_vc_id fetch cur_card_numbers into v_card_number;exit when cur_card_numbers%notfound;--dbms_output.put_line('v_card_number:' || v_card_number);--a.backup one record to voucher_card_oldinsert into voucher_card_old select * from voucher_card vc where vc.card_number = v_card_number;--b.delete one record from voucher_carddelete from voucher_card vc where vc.card_number = v_card_number;--a.backup one record to gm_goods_inst_oldinsert into gm_goods_inst_old select * from gm_goods_inst ggi where ggi.goods_sn = v_card_number;--b.delete one record from gm_goods_instdelete from gm_goods_inst ggi where ggi.goods_sn = v_card_number;--d.insert into inventory_clear_record for tracking deleted dataexecute immediate 'insert into inventory_clear_record(card_number,create_time) values(:a,:b)' using v_card_number ,sysdate ;--dbms_output.put_line('rowcount:' || cur_card_numbers%rowcount);-- 1000 once ,commitif mod(cur_card_numbers%rowcount,1000) = 0 then commit;--dbms_output.put_line('batch commit:' || cur_card_numbers%rowcount); end if ;end loop;--close cursorif cur_card_numbers%isopen thenclose cur_card_numbers;end if;commit;--excption exceptionwhen others thenrollback; end Proc_Clean_Inventory_Data;數據量較少
如果數據量較少,可以直接將數據加載到游標中,分多次執行。
create or replace procedure Proc_Clean_Inventory_Data authid current_user isv_card_number voucher_card.card_number%type;v_inventory_clean_record_num number(3);v_createRecordTableSql varchar2(1000);-- cusrosr card_number collection cursor cur_card_numbers is select card_number from voucher_card vcwhere vc.card_number in(select goods_snfrom gm_goods_instwhere GOODS_TYPE_ID = 'V'and GOODS_STATE = 'C'and state_date < sysdate - 50)--and rownum <= 100000 ;beginv_createRecordTableSql :='create table inventory_clear_record(card_number VARCHAR2(60),create_time DATE)'; -- check exists or not select count(1) into v_inventory_clean_record_num from user_tables ut where ut.TABLE_NAME = 'INVENTORY_CLEAR_RECORD';-- create inventory_clear_record for onceif v_inventory_clean_record_num = 0 then execute immediate v_createRecordTableSql ;end if ; /******Clean expired Data in voucher_card And gm_goods_inst******/--open cur_card_numbers,execute the cursor define sqlopen cur_card_numbers;--begin to looploop-- fetch one record into v_vc_id fetch cur_card_numbers into v_card_number;exit when cur_card_numbers%notfound;--dbms_output.put_line('v_card_number:' || v_card_number);--a.backup one record to voucher_card_oldinsert into voucher_card_old select * from voucher_card vc where vc.card_number = v_card_number;--b.delete one record from voucher_carddelete from voucher_card vc where vc.card_number = v_card_number;--a.backup one record to gm_goods_inst_oldinsert into gm_goods_inst_old select * from gm_goods_inst ggi where ggi.goods_sn = v_card_number;--b.delete one record from gm_goods_instdelete from gm_goods_inst ggi where ggi.goods_sn = v_card_number;--d.insert into inventory_clear_record for tracking deleted dataexecute immediate 'insert into inventory_clear_record(card_number,create_time) values(:a,:b)' using v_card_number ,sysdate ;--dbms_output.put_line('rowcount:' || cur_card_numbers%rowcount);-- 1000 once ,commitif mod(cur_card_numbers%rowcount,1000) = 0 then commit;--dbms_output.put_line('batch commit:' || cur_card_numbers%rowcount); end if ; end loop;--close cursorif cur_card_numbers%isopen thenclose cur_card_numbers;end if;commit;--excption exceptionwhen others thenrollback; end Proc_Clean_Inventory_Data;配置Job ,定時執行
beginsys.dbms_job.submit(job => :job,what => 'proc_clean_inventory_data;',next_date => to_date('09-05-2018 02:00:00', 'dd-mm-yyyy hh24:mi:ss'),interval => 'TRUNC(sysdate+1)+2/24');commit; end; /定期進行表分析
我們這兩個表是分區表,表分析SQL如下,主要是 GRANULARITY
BEGIN DBMS_STATS.GATHER_TABLE_STATS(OWNNAME => 'CRM',TABNAME => 'GM_GOODS_INST',ESTIMATE_PERCENT => DBMS_STATS.AUTO_SAMPLE_SIZE,METHOD_OPT => 'for all columns size repeat',DEGREE => 4,GRANULARITY => 'ALL',CASCADE => TRUE,no_invalidate => false);END; BEGINDBMS_STATS.GATHER_TABLE_STATS(OWNNAME => 'CRM',TABNAME => 'VOUCHER_CARD',ESTIMATE_PERCENT => DBMS_STATS.AUTO_SAMPLE_SIZE,METHOD_OPT => 'for all columns size repeat',DEGREE => 4,GRANULARITY => 'ALL',CASCADE => TRUE,no_invalidate => false); END;總結
以上是生活随笔為你收集整理的Oralce-清除数据的两种思路的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MyBatis-25MyBatis缓存配
- 下一篇: SSM-Spring+SpringMVC