views:

2042

answers:

5

I am encountering an issue where Oracle is very slow when I attempt to delete rows from a table which contains two CLOB fields. The table has millions of rows, no constraints, and the deletes are based on the Primary Key. I have rebuilt indexes and recomputed statistics, to no avail.

What can I do to improve the performance of deletes from this table?

+1  A: 

With Oracle you have to consider the amount of redo you are generating when deleting a row. If the CLOB fields are very big, it may just take awhile for Oracle to delete them due to the amount of redo being written and there may not be much you can do.

A test you may perform is seeing if the delete takes a long time on a row, where both CLOB fields are set to null. If that's the case, then it may be the index updates taking a long time. If that is the case, you may need to investigate consolidating indexes if possible, if deletes occur very frequently.

If the table is a derived table, meaning, it can be rebuilt from other tables, you may look at the NOLOGGING option on the table. You can the rebuild the table from the source table, with minimal logging.

I hope this entry helps some, however some more details could help diagnose the issue.

Nick
Thanks Nick. The last test I ran had the CLOB fields nulled out and the delete was still slow. There are only two indexes, a PK index on a single column and a FK index on a single column.These indexes aren't any different from others in the DB size wise.
bitstream
How many tables have foreign key constraints to your table? Regardless of the number, you want to check to see if those tables, the id referencing this table is indexed. If they aren't this could be the source of your problem.
Nick
+2  A: 

Trace it, with waits enabled

http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_monitor.htm#i1003679

Find the trace file in the UDUMP directory. TKPROF it. Look at the end and it will tell you what the database spent its time doing during that SQL. The following link is a good overview of how to analyze a performance issue.

http://www.method-r.com/downloads/doc_download/10-for-developers-making-friends-with-the-oracle-database-cary-millsap
Gary
Very cool. I'm going to try this today. Thanks!
bitstream
+1  A: 

Are there any child tables that reference this table from which are deleting? (You can do a select from user_constraints where r_constraint_name = primary key name on the table you are deleting from).

A delete can be slow if Oracle needs to look into another table to check there are no child records. Normal practice is to index all foreign keys on the child tables so this is not a problem.

Follow Gary's advice, perform the trace and post the TKPROF results here someone will be able to help further.

WW
There are no constraints.
bitstream
+1  A: 

Your UNDO tablespace seems to be the bottleneck in this case.

Check how long it takes to make a ROLLBACK after you delete the data. If it takes time comparable to the time of the query itself (within 50%), then this certainly is the case.

When you perform a DML query, your data (both original and changed) are written into redo logs and then applied to the datafiles and to the UNDO tablespace.

Deleting millions of CLOB rows takes copying several hundreds of megabytes, if not gigabytes, to the UNDO tablespace, which takes tens of seconds itself.

What can you do about this?

  1. Create a faster UNDO: put it onto a separate disk, make it less sparse (create a larger datafile).
  2. Use ROLLBACK SEGMENTS instead of managed UNDO, assign a ROLLBACK SEGMENT for this very query and issue SET TRANSACTION USE ROLLBACK SEGMENT before running the query.

If it's not the case, i. e. ROLLBACK executes much faster that the query itself, then try to play with you REDO parameters:

  1. Increase your REDO buffer size using LOG_BUFFER parameter.
  2. Increate the size of your logfiles.
  3. Create your logfiles on separate disks so that reading from a first datafile does not hinder writing to a second an so on.

Note that UNDO operations also generate REDO, so it's useful to do all this anyway.

NOLOGGING adviced before is useless, as it is applied only to certain set of operations listed here, DELETE not being one of those operations.

Quassnoi
A: 

Deleted CLOBs do not end up in the UNDOTBS since they are versioned and retented in the LOB Segment. I think it will generate some LOBINDEX changes in the undo.

If you null or empty the LOBs before, did you actually measured that time with commit separate of the DELETE? If you issue thousands of deletes, do you use batch commits? Is the instance idle? Then AWR report should tell you what is going on.

eckes