带有或语句的SQL查询执行时间太长

时间:2013-07-04 12:47:32

标签: sql performance oracle

我有一个包含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。

谢谢

2 个答案:

答案 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-尝试索引连接中包含的列。