Say I have two tables:
create table parent (
id number not null,
constraint parent_pk primary key(id),
)
create table child (
id number not null,
parent_id number not null,
constraint child_pk primary key(id),
constraint child_fk1 foreign key(parent_id)
references parent(id)
)
The parent table is big, say, 3 millions records. Now I run delete statement:
delete from parent; //even without where clause
Could you please explain what actually happens when this statement is executed? Where is no “ON DELETE CASCADE” option specified, as far as I understand it means that delete from parent table should fail if the child table contains references to parent id. So this means that before deleting the row from parent table Oracle should check if any child records exists. But this is really extremely slow – it’s row-by-row delete.
Am I correct? If not, please explain how Oracle works when deleting from parent table and check whether there are no orphans left in child table?
Here’s a test. My PARENT table has 100000 rows. Against an empty CHILD table (with an index on PARENT_ID) deletion takes this long:
Let’s insert some rows into CHILD. This will generate one row for every row in PARENT
If we delete from parent now, it fails instantly.
Whereas, if we have every record in CHILD point to just one record in PARENT it takes a bit longer…
Wallclock timings are notoriously unreliable, but that looks like roughly the same amount of time. And as it happens, the time to delete the PARENT table without foreign key dependencies is in the same ballpark:
So, basically, there is little or no overhead to check the foreign key constraint
There is a proviso: this is true providing the foreign key column is indexed. I dropped the CHILD_FK1_I index, and the
delete from parentstatement still hasn’t finished in the time it’s taken me to type up this response i.e. about ten minutes.