我怎样才能打破这个相关的sql-> oracle语句?

时间:2013-03-19 19:19:16

标签: sql oracle correlated-subquery

UPDATE t1
   SET t1.language_id = (SELECT distinct(CASE WHEN NETWORK.nid = 11 
                                  THEN 10
                                  ELSE 7
                              END)
                       FROM PROFILE,
                            NETWORK
                      WHERE PROFILE.STATUS IN ('A','U','S','H','I')
                        AND PROFILE.mid = t1.mid
                        AND NETWORK.mid = t1.mid
                        AND t1.is_deleted = 'N')

   AND EXISTS( SELECT 1

              FROM PROFILE,
                   NETWORK
             WHERE PROFILE.STATUS IN ('A','U','S','H','I')
               AND PROFILE.mid = t1.mid
               AND NETWORK.mid = t1.mid
               AND t1.is_deleted = 'N');

这是缓慢的方式。对使用语句使用不同的更新?为10做一次更新,为7做一次。

2 个答案:

答案 0 :(得分:1)

在查询t1表数据库中的每条记录时,对NETWORKPROFILE表执行单独的查询。实际上,您只需要扫描一次这个表。

我建议你使用MERGE子句:

merge into t1
using (
  select
    network.mid,
    decode(network.nid, 11, 10, 7) language_id,
  from
    profile,
    network
  where
    profile.status in ('A','U','S','H','I')
    and
    network.mid = profile.mid
) update_set 
on
  t1.mid = update_set.mid 
  and
  t1.is_deleted = 'N'
when matched
  then update set t1.language_id = update_set.language_id
;

有关详细信息,请查找description in Oracle documentation

答案 1 :(得分:0)

检查MID列的索引和统计信息(我假设选择性很高)。 检查执行计划。检查PQ / PDML。 如果您的MID是所有方面的UNIQUE列,您可以将其更改为:

UPDATE t1
SET t1.language_id = (SELECT distinct(CASE WHEN NETWORK.nid = 11 
                              THEN 10
                              ELSE 7
                          END)
                   FROM NETWORK
                   where NETWORK.mid = t1.mid
                   )
WHERE EXIST ( SELECT 1 from NETWORK where NETWORK.mid = t1.mid )
AND EXISTS( SELECT 1 FROM PROFILE where PROFILE.STATUS IN ('A','U','S','H','I')
                    AND PROFILE.mid = t1.mid )
AND t1.is_deleted = 'N'