diff --git a/divers/bulk_operations.md b/divers/bulk_operations.md new file mode 100644 index 0000000..309921a --- /dev/null +++ b/divers/bulk_operations.md @@ -0,0 +1,155 @@ +> https://medium.com/@ramazan.ozdemir/bulk-operations-in-oracle-database-bulk-insert-bulk-update-and-bulk-delete-0a1b9074cb0e + +Setup: +```sql +create user if not exists SAMPLE no authentication; +grant connect, resource, unlimited tablespace to SAMPLE; + +drop table if exists SAMPLE.RANDOM_DATA_LOAD purge; +create table SAMPLE.RANDOM_DATA_LOAD ( + id_col NUMBER, + text_col VARCHAR2(30), + date_col DATE +); + + +SET SERVEROUTPUT ON; + +DECLARE + -- Parameters + v_total_rows NUMBER := 10000000; -- Total lines to insert + v_start_date DATE := DATE '2020-01-01'; -- Range start + v_end_date DATE := DATE '2025-12-31'; -- Range end + + -- Internal variables + v_date_range NUMBER; +BEGIN + v_date_range := v_end_date - v_start_date; + + FOR i IN 1 .. v_total_rows LOOP + INSERT INTO SAMPLE.RANDOM_DATA_LOAD ( + id_col, + text_col, + date_col + ) VALUES ( + i, -- Distinct integer + DBMS_RANDOM.STRING('A', 30), -- Random string (Alphanumeric) + v_start_date + DBMS_RANDOM.VALUE(0, v_date_range) -- Random date in range + ); + + -- Optional: Commit every 10,000 rows to keep undo logs manageable + IF MOD(i, 10000) = 0 THEN + COMMIT; + END IF; + END LOOP; + + COMMIT; + DBMS_OUTPUT.PUT_LINE('Successfully inserted ' || v_total_rows || ' rows.'); +END; +/ + + +alter table SAMPLE.RANDOM_DATA_LOAD + add constraint RANDOM_DATA_LOAD_PK PRIMARY KEY (id_col); + +exec dbms_stats.gather_table_stats(ownname=>'SAMPLE',tabname=>'RANDOM_DATA_LOAD',method_opt=>'for all columns size AUTO'); +``` + +Bulk delete: +```sql +var my_action VARCHAR2(30); +exec :my_action:='bulk delete'; + +@login +select sysdate from dual; + +exec DBMS_APPLICATION_INFO.SET_ACTION (action_name => :my_action); + +DECLARE + TYPE id_col_table_type IS TABLE OF SAMPLE.RANDOM_DATA_LOAD.id_col%TYPE; + id_col_table id_col_table_type; + +BEGIN + -- Retrieve data to be deleted in bulk + SELECT id_col BULK COLLECT INTO id_col_table FROM SAMPLE.RANDOM_DATA_LOAD WHERE date_col <= date'2022-06-15'; + + -- Perform bulk delete + FORALL i IN 1..id_col_table.COUNT + DELETE FROM SAMPLE.RANDOM_DATA_LOAD WHERE id_col = id_col_table(i); + + COMMIT; +END; +/ + +select sysdate from dual; + +exec DBMS_APPLICATION_INFO.SET_ACTION (action_name => NULL); +``` + +Classic delete 1: +```sql +var my_action VARCHAR2(30); +exec :my_action:='classic delete 1'; + +@login +select sysdate from dual; + +exec DBMS_APPLICATION_INFO.SET_ACTION (action_name => :my_action); + +delete from SAMPLE.RANDOM_DATA_LOAD where id_col in (select id_col from SAMPLE.RANDOM_DATA_LOAD WHERE date_col <= date'2022-06-15'); + +select sysdate from dual; + +exec DBMS_APPLICATION_INFO.SET_ACTION (action_name => NULL); +``` + +Classic delete 2: +```sql +var my_action VARCHAR2(30); +exec :my_action:='classic delete 2'; + +@login +select sysdate from dual; + +exec DBMS_APPLICATION_INFO.SET_ACTION (action_name => :my_action); + +delete from SAMPLE.RANDOM_DATA_LOAD where date_col <= date'2022-06-15'; + +select sysdate from dual; + +exec DBMS_APPLICATION_INFO.SET_ACTION (action_name => NULL); +``` + +``` +bulk delete +----------- + +DELETE FROM SAMPLE.RANDOM_DATA_LOAD WHERE ID_COL = :B1 + + Elapsed CPU IO + End Plan Buffer time time time + Snap snaphot hash 0ptimizer Buffer gets SQL Disk /exec /exec /exec Elig Inter +Instance Id time value cost #Ex #EOF gets /exec Prof Px reads (sec) (sec) (sec) Mb Mb #Rows +-------- -------- ----------- ---------- ---------- -------- -------- ---------- ----------- ---- ------ ---------- ------- ----- ------ ------- ------- ---------- +NABOOPRD 3 01/05 15:49 2400881684 2 1 1 20971850 20971850 0 83 170 103 0 0 1 4089976 + + +classic delete 1 +---------------- Elapsed CPU IO + End Plan Buffer time time time + Snap snaphot hash 0ptimizer Buffer gets SQL Disk /exec /exec /exec Elig Inter +Instance Id time value cost #Ex #EOF gets /exec Prof Px reads (sec) (sec) (sec) Mb Mb #Rows +-------- -------- ----------- ---------- ---------- -------- -------- ---------- ----------- ---- ------ ---------- ------- ----- ------ ------- ------- ---------- +NABOOPRD 4 01/05 16:03 1336456799 18858 1 1 12570950 12570950 0 22165 93 52 0 0 173 4089976 + + + +classic delete 2 +---------------- Elapsed CPU IO + End Plan Buffer time time time + Snap snaphot hash 0ptimizer Buffer gets SQL Disk /exec /exec /exec Elig Inter +Instance Id time value cost #Ex #EOF gets /exec Prof Px reads (sec) (sec) (sec) Mb Mb #Rows +-------- -------- ----------- ---------- ---------- -------- -------- ---------- ----------- ---- ------ ---------- ------- ----- ------ ------- ------- ---------- +NABOOPRD 5 01/05 16:18 1336456799 18858 1 1 12562664 12562664 0 25260 91 51 0 0 197 4089976 +``` + diff --git a/divers/purge_all_AWR_snap.md b/divers/purge_all_AWR_snap.md new file mode 100644 index 0000000..8fe726a --- /dev/null +++ b/divers/purge_all_AWR_snap.md @@ -0,0 +1,51 @@ +## Purge all AWR snapshots + +> To run from `CDB$ROOT` and not inside a **PDB**. + +```sql +DECLARE + v_lo_snap_id NUMBER; + v_hi_snap_id NUMBER; + v_awr_dbid NUMBER; +BEGIN + -- 1. Get the DBID that actually exists in the AWR repository + SELECT DISTINCT dbid INTO v_awr_dbid FROM dba_hist_snapshot WHERE ROWNUM = 1; + + -- 2. Find the min and max snapshot IDs for that specific DBID + SELECT min(snap_id), max(snap_id) + INTO v_lo_snap_id, v_hi_snap_id + FROM dba_hist_snapshot + WHERE dbid = v_awr_dbid; + + IF v_lo_snap_id IS NOT NULL THEN + DBMS_OUTPUT.PUT_LINE('Deleting snapshots for DBID ' || v_awr_dbid || + ' from ' || v_lo_snap_id || ' to ' || v_hi_snap_id); + + DBMS_WORKLOAD_REPOSITORY.DROP_SNAPSHOT_RANGE( + low_snap_id => v_lo_snap_id, + high_snap_id => v_hi_snap_id, + dbid => v_awr_dbid + ); + + DBMS_OUTPUT.PUT_LINE('AWR Snapshots cleared.'); + ELSE + DBMS_OUTPUT.PUT_LINE('No snapshots found in dba_hist_snapshot.'); + END IF; +EXCEPTION + WHEN TOO_MANY_ROWS THEN + DBMS_OUTPUT.PUT_LINE('Error: Multiple DBIDs found in AWR. Please specify one manually.'); + WHEN NO_DATA_FOUND THEN + DBMS_OUTPUT.PUT_LINE('Error: No snapshot data exists to delete.'); +END; +/ +``` + +Verify: +```sql +select min(snap_id),max(snap_id), dbid from dba_hist_snapshot group by dbid; +``` + +To take a snapshot: +```sql +execute dbms_workload_repository.CREATE_SNAPSHOT; +```