Files
notes/divers/bulk_operations.md
T
2026-05-01 16:48:01 +02:00

5.9 KiB

https://medium.com/@ramazan.ozdemir/bulk-operations-in-oracle-database-bulk-insert-bulk-update-and-bulk-delete-0a1b9074cb0e

Setup:

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:

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:

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:

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