有两个表,一个是根据第二个表更新的。SQL正在工作,但是由于记录的数量,它花费了太多的时间,我认为。见这小提琴。实际主表包含1,500,000条,子表包含700,000条记录,以下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的执行计划是(红一个是主的,另一个是子的)

seqn是主键。毫无疑问,这一切都取决于服务器的性能和索引的状态。然而,让我感到困扰的是,master没有被索引所访问,并且被读取了两次。有可能对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的解决方案将无法工作。
发布于 2013-11-12 05:43:39
看看这个:
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;小提琴:http://www.sqlfiddle.com/#!4/c6b73/2
你刚刚在小提琴里错过了PK。
https://stackoverflow.com/questions/19921656
复制相似问题