Reputation: 4121
We have a feed process which runs every day of the year. As part of that we delete every row from a table (approx 1 million rows) every day, repopulate it using 5 different stored procedures and then commit the transaction. This is the only commit statement that we call. All of a sudden the delete has started takign about 2 hours to complete. The delete is also very simple (delete from T_PROFILE_WORK) This has worked perfectly well for the past year, but in the past week I have noticed this issue.
Any help on this is greatly appreciated
Upvotes: 2
Views: 4321
Reputation: 9514
For the record, here is the script from Tom Kyte and mentioned by Vincent Malgrat in the accepted answer (so that you don't have to sift through the gazillion comments and follow more links).
The script yields all the columns for all the tables; you still have to figure out which ones apply to the table where you want to delete rows and which FK tables have the largest cardinality.
Said otherwise, not all hits need an index of course.
SELECT table_name,
constraint_name,
cname1
|| NVL2 (cname2, ',' || cname2, NULL)
|| NVL2 (cname3, ',' || cname3, NULL)
|| NVL2 (cname4, ',' || cname4, NULL)
|| NVL2 (cname5, ',' || cname5, NULL)
|| NVL2 (cname6, ',' || cname6, NULL)
|| NVL2 (cname7, ',' || cname7, NULL)
|| NVL2 (cname8, ',' || cname8, NULL)
columns
FROM ( SELECT b.table_name,
b.constraint_name,
MAX (DECODE (position, 1, column_name, NULL)) cname1,
MAX (DECODE (position, 2, column_name, NULL)) cname2,
MAX (DECODE (position, 3, column_name, NULL)) cname3,
MAX (DECODE (position, 4, column_name, NULL)) cname4,
MAX (DECODE (position, 5, column_name, NULL)) cname5,
MAX (DECODE (position, 6, column_name, NULL)) cname6,
MAX (DECODE (position, 7, column_name, NULL)) cname7,
MAX (DECODE (position, 8, column_name, NULL)) cname8,
COUNT (*) col_cnt
FROM (SELECT SUBSTR (table_name, 1, 30) table_name,
SUBSTR (constraint_name, 1, 30) constraint_name,
SUBSTR (column_name, 1, 30) column_name,
position
FROM user_cons_columns) a, user_constraints b
WHERE a.constraint_name = b.constraint_name
AND b.constraint_type = 'R'
GROUP BY b.table_name, b.constraint_name) cons
WHERE col_cnt >
ALL ( SELECT COUNT (*)
FROM user_ind_columns i
WHERE i.table_name = cons.table_name
AND i.column_name IN
(cname1,
cname2,
cname3,
cname4,
cname5,
cname6,
cname7,
cname8)
AND i.column_position <= cons.col_cnt
GROUP BY i.index_name);
Upvotes: 0
Reputation: 35401
How about you have a second (perhaps global temporary) table which you populate from the stored procedures and, at the end, do a MERGE into the existing table. Without know the details of the activity, table structures etc, it is hard to be certain. But you may find it quicker.
As an alternative, if you have Enterprise Edition with the partitioning option, look at partition exchange.
Upvotes: 0
Reputation: 67742
please review the answers of this SO Question: "oracle delete query taking too much time":
- You could be blocked by another session (most likely). Before you delete you should make sure noone else is locking the rows, eg: issue SELECT NULL FROM tablename WHERE colname=:value FOR UPDATE NOWAIT,
- There could be a ON DELETE TRIGGER that does additional work,
- Check for UNINDEXED REFERENCE CONSTRAINTS pointing to this table (there is a script from AskTom that will help you determine if such unindexed foreign keys exist).
I would check #2 and #3 first, they are the easiest to diagnose.
Upvotes: 5
Reputation: 10541
If you just want to remove everything from the table use truncate instead of delete.
Upvotes: 2