我有一个包含2列的表--ref_table_id,ref_objid。 该表用于引用其他表中的对象。它实际上有两列以上,但其他列并不重要。
以下查询需要1秒才能执行:
delete from ref_table_id
where (ref_table_id = 1 and
ref_objid not in (select objid from table1))
此查询也需要1秒钟才能执行:
delete from ref_table_id
where (ref_table_id = 2 and
ref_objid not in (select objid from table2))
但是此查询需要3分钟才能执行:
delete from ref_table_id
where (ref_table_id = 1 and
ref_objid not in (select objid from table1))
or (ref_table_id = 2 and
ref_objid not in (select objid from table2))
为什么最后一个查询花了这么多时间?它基本上只是前两者的组合。有人可以解释一下吗?
我正在使用Oracle。
谢谢
答案 0 :(得分:1)
or
条款中的where
使Oracle变得非常慢。原因是在这些条件下不能使用索引。
在这种情况下,您最好执行两个单独的delete
语句。
如果您迫切希望在一个声明中这样做,您可能想尝试这个:
delete from ref_table_id
where
id in
( select id from ref_table_id
where
ref_table_id = 1 and
ref_objid not in (select objid from table1)
union all
select id from ref_table_id
where
ref_table_id = 2 and
ref_objid not in (select objid from table2)
)
union all
速度非常快,无法使用or
。但另一方面,它使语句更复杂,所以就像我说的那样,执行两次删除可能要容易得多。
答案 1 :(得分:0)
有很多原因导致oracle查询需要这么长时间,但在这种情况下我会猜测:
1-内部选择(从table1中选择objid并从table2中选择objid)必须在每一行上进行评估。
2-由于陈旧的统计数据,oracle正在创建一个糟糕的执行计划,尝试收集新的统计数据。
3-尝试索引连接中包含的列。