优化sql更新语法而不是服务器

优化sql更新语法而不是服务器,sql,oracle,optimization,oracle11g,query-optimization,Sql,Oracle,Optimization,Oracle11g,Query Optimization,有两个表,一个是基于第二个表更新的。SQL正在工作,但我认为由于记录的数量,它花费了太多的时间。看小提琴。实际的主表包含1500000条记录,子表包含700000条记录,下面的sql持续执行4小时,因此终止 UPDATE master m SET m.amnt = (SELECT amnt FROM child c WHERE c.seqn = m.seqn) WHERE m.seqn IN (SELECT seqn FROM child); 此sql的执行计划是(红色的一个是主sql,另一个

有两个表,一个是基于第二个表更新的。SQL正在工作,但我认为由于记录的数量,它花费了太多的时间。看小提琴。实际的主表包含1500000条记录,子表包含700000条记录,下面的sql持续执行4小时,因此终止

UPDATE master m SET m.amnt = (SELECT amnt FROM child c WHERE c.seqn = m.seqn)
WHERE m.seqn IN (SELECT seqn FROM child);
此sql的执行计划是(红色的一个是主sql,另一个是子sql)

seqn
是主键。毫无疑问,这一切都取决于服务器的性能和索引的统计数据。然而,索引并没有访问master,而child被读取了两次,这让我很烦恼。sql可能已优化,但oracle决定采用这种方式,但我尝试将sql优化为

UPDATE (
SELECT m.seqn m_seqn,c.seqn c_seqn, c.amnt c_amnt, m.amnt m_amnt
FROM master m INNER JOIN child c ON m.seqn = c.seqn) 
SET m_amnt = c_amnt
这导致了以下错误

ORA-01779: cannot modify a column which maps to a non key-preserved 
table : UPDATE ( SELECT m.seqn m_seqn,c.seqn c_seqn, c.amnt c_amnt, m.amnt m_amnt 
FROM master m INNER JOIN child c ON m.seqn = c.seqn) SET m_amnt = c_amnt
除了更新统计数据和调整服务器之外,还有其他方法可以优化SQL吗

编辑如果要连接的列不是PK,@Sebas的解决方案将不起作用

请检查此解决方案:

UPDATE  
(
    SELECT m.amnt AS tochange, c.amnt AS newvalue 
    FROM child c 
        JOIN master m ON c.seqn = m.seqn
) t
SET t.tochange = t.newvalue;

SELECT * FROM master;
小提琴:


您刚刚错过了小提琴中的主键。

Hmmm,基本区别是在我的例子中,
seqn
notnull
唯一索引
,但不是
主键
。因此,它表明
主键
唯一索引+非空
是不同的!!!真有趣。至少在这种情况下!即使在将
seqn
修改为
Primary Key
之后,它仍然会给出相同的错误,可能是因为我的版本是11.1,SQLFIDLE使用的是11.2。太有趣了,你能调查一下吗?有趣!如果
child
seqn
唯一的
主键
,则查询将起作用。主人不需要任何东西