优化sql更新语法而不是服务器
有两个表,一个是基于第二个表更新的。SQL正在工作,但我认为由于记录的数量,它花费了太多的时间。看小提琴。实际的主表包含1500000条记录,子表包含700000条记录,下面的sql持续执行4小时,因此终止优化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,另一个
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
是唯一的
或主键
,则查询将起作用。主人不需要任何东西