0

我有一个有 2 列的表 - ref_table_id、ref_objid。该表用于引用其他表中的对象。它实际上有超过 2 列,但其他列并不重要。

以下查询需要 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))

为什么最后一个查询需要这么长时间?它基本上只是前两者的组合。谁能解释一下?

我正在使用甲骨文。

谢谢

4

2 回答 2

1

众所周知,Oracle 的orinwhere子句速度很慢。原因是在这些条件下也不能使用索引。

在这种情况下,您最好执行两个单独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. 但另一方面,它使语句更复杂,所以就像我说的,只执行两次删除可能会容易得多。

于 2013-07-04T13:26:32.310 回答
0

oracle 查询需要这么长时间的原因有很多,但在这种情况下,我猜:

1- 必须在每一行上评估内部选择(从 table1 中选择 objid 并从 table2 中选择 objid)。

2- 由于统计数据过时,oracle 正在创建错误的执行计划,尝试收集新的统计数据。

3-尝试索引连接中包含的列。

于 2013-07-04T12:51:32.737 回答