繁体   English   中英

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

[英]oracle delete query taking too much time

我有一个查询

DELETE from tablename where colname = value;

这需要很长时间才能执行。 可能是什么原因? 我有一个关于colname的索引。

可能有几个解释为什么您的查询需要很长时间:

  1. 您可能被另一个会话阻止(最有可能)。 在删除之前,您应该确保没有其他人锁定行,例如:发出SELECT NULL FROM tablename WHERE colname=:value FOR UPDATE NOWAIT
  2. 可能有一个ON DELETE TRIGGER做额外的工作,
  3. 检查指向此表的UNINDEXED REFERENCE CONSTRAINTS来自AskTom脚本将帮助您确定是否存在此类未编制索引的外键)。

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

该指数的选择性如何? 如果你的表有一百万行,并且该值达到十五万,那么你的索引就没用了。 事实上,如果实际使用它可能会比无用更糟糕。 请记住,DELETE类似于SELECT语句:我们可以调整其访问路径。

此外,删除会占用大量的撤消表空间,因此如果系统使用频繁,您可能会遇到争用。 在多用户系统中,另一个会话可能会锁定要删除的行。

你有ON DELETE触发器吗? 你有ON DELETE CASCADE外键约束吗?

编辑:鉴于您所说的一切,特别是有问题的列是主键,因此您尝试删除单行,如果需要很长时间,则其他进程或用户更有可能锁定排。 V$LOCK是否有任何显示?

您的表是否包含更多记录?
是否有一些在数据库服务器上运行的递归程序(一些嵌套循环等)?
如果数据库服务器在不同的机器上,请检查网络问

如果事情变慢,你不知道为什么,追踪并发现。

如何解决Oracle SQL语句的性能问题

所以我只想发布我的经验。 可能对某人有帮助。

查询

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

花了16秒。 从表格foo删除2300总共2300条记录。

我按照其他答案中的指示检查了外键上的所有索引。 这没有用。

解:

将查询更改为

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
);

我已经改变了not inin和用minus来实现正确的结果。

现在查询在0.04秒内执行。

Oracle和mysql之间存在显着差异:

Oracle不会自动为外键创建索引,但mysql会这样做。 然后,如果您有一些父表,您可以在其上执行delete命令,那么您必须在子表中的外键上创建索引,否则如果子表有很多行,父表上的delete命令将非常慢,因为它必须每次删除任何父记录时,浏览子表的所有记录。

当您想要从Oracle数据库中的父表中删除时要小心。

暂无
暂无

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

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