简体   繁体   中英

oracle delete query taking too much time

I have a query like

DELETE from tablename where colname = value;

which takes awfully long time to execute. What could be the reason? I have an index on colname.

There could be several explanations as to why your query takes a long time:

  1. 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 ,
  2. There could be a ON DELETE TRIGGER that does additional work,
  3. 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).

可能是你的表与多个表有很大的行数。

How selective is that index? If your table has one million rows and that value hits one hundred and fifty thousand of them then your index is useless. In fact it may be worse than useless if it is actually being used. Remember, a DELETE is a like a SELECT statement: we can tune its access path.

Also, deletes take up a lot of undo tablespace, so you might be suffereing from contention, if the system is experiencing heavy use. In a multi-user system another session might have a lock on the rows(s) you want to delete.

Do you have ON DELETE triggers? Do you have ON DELETE CASCADE foreign key constraints?

Edit: Given all that you say, and especially the column in question being the primary key so you are attempting to delete a single row, if it is taking a long time it is much more likely that some other process or user has a lock on the row. Is anything showing up in V$LOCK ?

Does your table holds more number of records ?
Is there some recursive programs(some nested loops etc..) running on the database server ?
Check network problems if database server is on different machines ?

If something's slow, and you don't know why, trace it and find out.

How do I troubleshoot performance problems with an Oracle SQL statement

So I'll just post my experience. Might be helpful for someone.

The query

delete from foo
where foo_id not in ( 
  select max(foo_id) from foo group by foo_bar_id, foo_qux_id
);

took 16 sec. deleting 1700 records from 2300 total in table foo .

I checked all the indexes on foreign keys as directed in other answers. That did not help.

Solution:

Changed the query to

delete from foo
where foo_id in ( 
  select foo_id from foo
  minus
  select max(foo_id) from foo group by foo_bar_id, foo_qux_id
);

I've changed not in to in and used minus to achieve correct result.

Now the query executes in 0.04 sec.

There is a significant difference between Oracle and mysql :

Oracle does not create index automatically for foreign keys but mysql does. Then if you have some parent table that you may execute delete command on it then you must create index on foreign keys in child tables otherwise the delete command on parent table will be very very slow if child tables has a lot of rows, because it must surf all records of child table per deletion of any parent records.

Then be careful when you want to delete from parent table in Oracle database.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM