2014-10-06 66 views
1

我有一个非常简单的SQL语句,它在Oracle 10g数据库上执行。它的一些数据移动从一个模式到另一个:Oracle声明挂起

CREATE TABLE TARGET.BIG_TABLE AS SELECT * FROM SOURCE.BIG_TABLE 
WHERE (COLUMN1, COLUMN2) IN (SELECT COLUMN1, COLUMN2 FROM TARGET.HELP_TABLE); 

有一个在TARGET.HELP_TABLE为COLUMN1和COLUMN2的唯一约束。在SOURCE.BIG_TABLE中只有一个组合的主键(COLUMN1,COLUMN2,COLUMN3,COLUMN4,COLUMN5)。

该语句本身没有问题,因为它已经在类似的测试环境中进行了多次测试。

但是,在真实环境下,该声明在大约3小时后没有任何I/O活动。 8小时后,我们中止了执行。

这种行为的原因是什么?我能做些什么来解决问题的根源?我绝对没有线索!

+0

它是否被未提交的事务锁定? – 2014-10-06 08:07:19

+0

理论上,这是不可能的。在执行语句之前,所有将事务写入源模式的进程都将关闭。但是,是否有可能知道为什么声明挂起或为何等待? – user3783827 2014-10-06 08:16:35

+3

查询可能需要很长时间。您是否在生产环境中检查了'EXPLAIN PLAN' [您的选择查询的结果](http://www.orafaq.com/wiki/Explain_Plan) – 2014-10-06 08:26:12

回答

1

尝试摆脱解释计划中的嵌套循环。考虑使用内部改写查询加盟:

SELECT /*+ use_hash(a b) */ 
     a.* 
    FROM SOURCE.BIG_TABLE a 
inner join (SELECT distinct COLUMN1, COLUMN2 FROM TARGET.HELP_TABLE) b 
    on b.COLUMN1 = a.COLUMN1 
    and b.COLUMN2 = a.COLUMN2; 

也可以考虑使用use_hash提示。选择所有行时不应使用索引(除非help_table中的column1和column2可能通过索引快速完整扫描返回)。仅当存在重复时,才在内部查询中使用distinct

考虑添加parallel提示。