首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >优化sql更新语法而不是服务器

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

Stack Overflow用户
提问于 2013-11-12 05:34:31
回答 1查看 64关注 0票数 2

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

代码语言:javascript
复制
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优化为

代码语言:javascript
复制
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

导致以下错误

代码语言:javascript
复制
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的解决方案将无法工作。

EN

回答 1

Stack Overflow用户

发布于 2013-11-12 05:43:39

看看这个:

代码语言:javascript
复制
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。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19921656

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档