简体   繁体   English

oracle删除查询花费了太多时间

[英]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. 我有一个关于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 , 在删除之前,您应该确保没有其他人锁定行,例如:发出SELECT NULL FROM tablename WHERE colname=:value FOR UPDATE NOWAIT
  2. There could be a ON DELETE TRIGGER that does additional work, 可能有一个ON DELETE TRIGGER做额外的工作,
  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). 检查指向此表的UNINDEXED REFERENCE CONSTRAINTS来自AskTom脚本将帮助您确定是否存在此类未编制索引的外键)。

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

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. 请记住,DELETE类似于SELECT语句:我们可以调整其访问路径。

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? 你有ON DELETE触发器吗? Do you have ON DELETE CASCADE foreign key constraints? 你有ON DELETE CASCADE外键约束吗?

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 ? 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 如何解决Oracle SQL语句的性能问题

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. 花了16秒。 deleting 1700 records from 2300 total in table foo . 从表格foo删除2300总共2300条记录。

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. 我已经改变了not inin和用minus来实现正确的结果。

Now the query executes in 0.04 sec. 现在查询在0.04秒内执行。

There is a significant difference between Oracle and mysql : Oracle和mysql之间存在显着差异:

Oracle does not create index automatically for foreign keys but mysql does. Oracle不会自动为外键创建索引,但mysql会这样做。 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. 然后,如果您有一些父表,您可以在其上执行delete命令,那么您必须在子表中的外键上创建索引,否则如果子表有很多行,父表上的delete命令将非常慢,因为它必须每次删除任何父记录时,浏览子表的所有记录。

Then be careful when you want to delete from parent table in Oracle database. 当您想要从Oracle数据库中的父表中删除时要小心。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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