Skip to Main Content

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Arslan Afzal.

Asked: May 29, 2024 - 3:44 pm UTC

Last updated: June 05, 2024 - 2:38 pm UTC

Version: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production

Viewed 1000+ times

You Asked

Hi,

I am working on a Archiving application. Aim is to bring year and years of data from Production DB into another DB named as Archiving DB and then delete from the Production DB. Currently I am testing deletion on an Archiving DB to test my package performance. I am running I query like mentioned below.

DELETE FROM IBE_BOOKEDPRODUCT p
   WHERE 
   parentbookingreference IS NULL AND
   EXISTS (
    SELECT 1
    FROM ARCHIVING_TEMP_TABLE_BOOKINGS a
    WHERE p.BOOKINGREFERENCE = a.BOOKINGREFERENCE
   );


Now the table ARCHIVING_TEMP_TABLE_BOOKINGS will have 50,000 booking references. Table IBE_BOOKEDPRODUCT has 100 of Million of rows. Currently where I am stuck, it should be removing around 450K rows from IBE_BOOKEDPRODUCT.

I have gone through your article on indexing Foreign Keys. 20 tables are using this table IBE_BOOKEDPRODUCT's columns. Mostly were unindexed. All these 20 tables also had Millions of rows.

I have tested thing thing earlier where my query was taking 40 minutes and once I indexed FKey (though here it was comprised of 1 column), it completed in 2 minutes.

However, in case of IBE_BOOKEDPRODUCT, it has around 10-12 columns which are being used as FKey. I indexed all and then it took strange more time like 3 hours and still not completed. Previously it was taking about 40 minutes. I have now removed indexes I created and am trying the logic again.

However, I need your suggestion how to optimize my logic.


Note: below is the explain plan of the running query
Query Plan, Rows, Rowsource Time(s)
DELETE STATEMENT   Cost = 175300        361
DELETE  IBE_BOOKEDPRODUCT         594
    NESTED LOOPS      413K 0
        NESTED LOOPS      413K 0
            SORT UNIQUE      50K 0
                TABLE ACCESS FULL ARCHIVING_TEMP_TABLE_BOOKINGS     50K 0
            INDEX RANGE SCAN XXBCF_IBEBOOKPROD002      8  0
        TABLE ACCESS BY INDEX ROWID IBE_BOOKEDPRODUCT      8  0


RowSource time is increasing in each refresh I do for top 2 lines.

and Connor said...

The NESTED LOOP in your plan implies we are doing the equivalent of a single row lookup into the IBE_BOOKEDPRODUCT table each of the candidate records found in ARCHIVING_TEMP_TABLE_BOOKINGS

Even though IBE_BOOKEDPRODUCT is large it *may* be more efficent to do a single scan of each table using HASH JOIN with something like

DELETE FROM IBE_BOOKEDPRODUCT p
   WHERE 
   parentbookingreference IS NULL AND p.BOOKINGREFERENCE in 
    SELECT a.BOOKINGREFERENCE
    FROM ARCHIVING_TEMP_TABLE_BOOKINGS a
   );


Alternatively, it might well be the case that its the deletion act itself - in which case, check for triggers, excessive indexes, or the number of child tables linked by FK.

A trace would possibly reveal more information, ie

- dbms_monitor.session_trace_enable(waits=>true)
- run delete
- dbms_monitor.session_trace_disable

and then check the (tkprof formatted) trace

Rating

  (2 ratings)

Comments

Arslan, May 30, 2024 - 7:35 am UTC

Hi,

Thanks for the response. I in my oracle package have around 70 such deletion scripts and I am using DELET FROM TABLE where EXIST. I have checked your article on EXIST vs IN. My reason was that TEMP table will be having 50,000 bookings. So I used EXIST even though the target or outer table has million of records. If I go with your suggestion, that means if I use IN statement, IBE_BOOKEDPORDUCT will be scanned only once.

Right on this?
Connor McDonald
June 05, 2024 - 2:32 pm UTC

Most probably. We can't see your environment, but you can check this by looking at the execution plan.

Partitioning...

rajeshwaran jeyabal, June 04, 2024 - 1:45 am UTC

when you say this
....
Aim is to bring year and years of data from Production DB into another DB named as Archiving DB and then delete from the Production DB
....

that sounds like the need for partitioning,
but that involves change to the data model, which might be worth to consider.

Connor McDonald
June 05, 2024 - 2:38 pm UTC

be aware its a licensable option

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library