[英]oracle delete query taking too much time
我有一个查询
DELETE from tablename where colname = value;
这需要很长时间才能执行。 可能是什么原因? 我有一个关于colname的索引。
可能是你的表与多个表有很大的行数。
该指数的选择性如何? 如果你的表有一百万行,并且该值达到十五万,那么你的索引就没用了。 事实上,如果实际使用它可能会比无用更糟糕。 请记住,DELETE类似于SELECT语句:我们可以调整其访问路径。
此外,删除会占用大量的撤消表空间,因此如果系统使用频繁,您可能会遇到争用。 在多用户系统中,另一个会话可能会锁定要删除的行。
你有ON DELETE触发器吗? 你有ON DELETE CASCADE外键约束吗?
编辑:鉴于您所说的一切,特别是有问题的列是主键,因此您尝试删除单行,如果需要很长时间,则其他进程或用户更有可能锁定排。 V$LOCK
是否有任何显示?
您的表是否包含更多记录?
是否有一些在数据库服务器上运行的递归程序(一些嵌套循环等)?
如果数据库服务器在不同的机器上,请检查网络问
如果事情变慢,你不知道为什么,追踪并发现。
所以我只想发布我的经验。 可能对某人有帮助。
查询
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 in
以in
和用minus
来实现正确的结果。
现在查询在0.04秒内执行。
Oracle和mysql之间存在显着差异:
Oracle不会自动为外键创建索引,但mysql会这样做。 然后,如果您有一些父表,您可以在其上执行delete命令,那么您必须在子表中的外键上创建索引,否则如果子表有很多行,父表上的delete命令将非常慢,因为它必须每次删除任何父记录时,浏览子表的所有记录。
当您想要从Oracle数据库中的父表中删除时要小心。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.