2好像写错了,应该是
2.
update tab_a set col_a='aa'
where EXISTS
(
   select * from tab_b where tab_a.col_b=tab_b.col_b
   and tab_b.col_b='bb'
)
and col_c='cc'

解决方案 »

  1.   

    查询的时候,筛选量最大的语句放在最后面,如果
    EXISTS
    (
       select * from tab_b where tab_a.col_b=tab_b.col_b
       
    ) 可以筛选出大量的数据的话,就把它放在后面
      

  2.   

    1. 最好将对应的执行计划贴出来瞧瞧再说
    2. 建议将exists字句中的select * 替换为 select 1
    3. 对于子查询的数据量小于主表的数据量, 可以考虑使用anti hash join
    update table_a a set col1 = ..,col2 = ... 
    where exists ( 
      select /*+hash_aj(a,b)*/ 1 from table_b b where a.col = b.col
    )
      

  3.   

    我贴出来,大家看看是否有好的办法,现在由于这个数据量太大的问题真的弄的很痛苦
    UPDATE SAL_TB_IMEI SET ERRORREASON=2,STEP=2,ISCOUNT=0
    WHERE NOT EXISTS
    (
       SELECT * FROM 
       (
          select dd.imei from sys_v_sortjoinallunique cc
          inner join sal_tb_saleswbk aa 
          on lower(substr(aa.goodsid,0,6))=lower(cc.allunique) 
          inner join sal_tb_khxstz dd
          on aa.orderid=dd.orderid and aa.goodsid=dd.goodsid
          where aa.organid='gxbc' and aa.clientid='C00003477' 
          and cc.sortid='4723' and aa.clientnameid=0 
       ) B WHERE B.IMEI=SAL_TB_IMEI.IMEI
    )
    AND SAL_TB_IMEI.SPID=11 AND SAL_TB_IMEI.ERRORREASON=0 AND SAL_TB_IMEI.SORTID='4723';SAL_TB_IMEI 表 主键spid,imei,记录目前只有几千笔
    sal_tb_khxstz 主键orderid,imei 大概有300多万笔记录
    sal_tb_saleswbk 主键orderid,sid 大概30多万笔记录
    sys_v_sortjoinallunique 记录非常少我执行一次需要几个小时-_-||| 
    SQL 语句:UPDATE SAL_TB_IMEI SET ERRORREASON=2,STEP=2,ISCOUNT=0
    WHERE NOT EXISTS
    (
       SELECT * FROM 
       (
          select dd.imei from sys_v_sortjoinallunique cc
          inner join sal_tb_saleswbk aa 
          on lower(substr(aa.goodsid,0,6))=lower(cc.allunique) 
          inner join sal_tb_khxstz dd
          on aa.orderid=dd.orderid and aa.goodsid=dd.goodsid
          where aa.organid='gxbc' and aa.clientid='C00003477' 
          and cc.sortid='4723' and aa.clientnameid=0 
       ) B WHERE B.IMEI=SAL_TB_IMEI.IMEI
    )
    AND SAL_TB_IMEI.SPID=11 AND SAL_TB_IMEI.ERRORREASON=0 AND SAL_TB_IMEI.SORTID='4723'使用的优化程序模式:   COST ALL ROWS (优化程序: CHOOSE) 总成本:   2 执行步骤:步骤号 步骤名 
    13  UPDATE STATEMENT 
    12  UPDATE 
    11  ERPSYS.INDEX_SAL_TB_IMEI INDEX [RANGE SCAN] 
    10  SORT [GROUP BY] 
    9  HASH JOIN 
    7  FILTER 
    6  MERGE JOIN [OUTER] 
    3  NESTED LOOPS 
    1  ERPSYS.GOODSORTPRI INDEX [UNIQUE SCAN] 
    2  ERPSYS.INDEX_1 INDEX [FAST FULL SCAN] 
    5  BUFFER [SORT] 
    4  ERPSYS.SYS_TB_GOODSSORTCODING TABLE ACCESS [FULL] 
    8  ERPSYS.SAL_TB_KHXSTZ TABLE ACCESS [FULL] 步骤号 说明 估计成本 估计的返回行数 估计的返回字节数 (KB) 
      1    此计划步骤检索 B*-tree 索引 GOODSORTPRI 中的单个 ROWID。 1 1 0.013 
      2    此计划步骤通过依次扫描叶节点来检索 B*-tree 索引 INDEX_1 中的所有 ROWID。 4 1 0.098 
      3    此计划步骤通过对驱动即外部行集 (联接的第一个子级) 进行迭代, 并且对每行执行内部行集 (联接的第二个子级) 的步骤来联接两组行。根据查询的 WHERE 子句所指定的联接条件测试相应行对。 5 1 0.11 
      4    此计划步骤检索表 SYS_TB_GOODSSORTCODING 中的所有行。 4 23 0.562 
      5    此计划步骤对缓冲区行源排序。 5 23 0.562 
      6    该计划步骤接受按联接关键字排序的两个行集。以联接关键字的顺序浏览两个行集, 通过一次传递这两个行集可以找到每个满足 WHERE 子句中的联接条件的独特行对。除匹配的行外, Oracle 还返回行集中未包含外部联接运算符 (+) 因而未能满足条件的所有行。 -- -- -- 
      7    此计划步骤从其子节点接受一组行, 删除其中一些行, 再返回其余的行。    
      8    此计划步骤检索表 SAL_TB_KHXSTZ 中的所有行。 752 6,374 242.76 
      9    此计划步骤接受两组行, 分别来自不同的表。已经使用第一个子级所返回的行构建散列表。第二个子级返回的每行接着用于探测散列表以查找满足查询的 WHERE 子句中指定条件的行对。注: Oracle 基于成本的优化程序将使用两个表中它认为较小的表来构建散列表。优化程序利用统计信息来确定较小的表。因此, 过期的统计信息可能会导致优化程序做出错误的选择。 762 7 1.21 
      10    此计划步骤接受来自其子级节点的一个行集, 并按照查询的 GROUP BY 子句中指定的列对这些行进行分组。 764 7 1.21 
      11    此计划步骤通过扫描 B*-tree 索引 INDEX_SAL_TB_IMEI 来检索一个或多个 ROWID (按升序排列)。 2 1 0.098 
      12    此计划步骤更新表 SAL_TB_IMEI 中满足 UPDATE 语句的 WHERE 子句的那些行。    
      13    此计划步骤将该语句指定为 UPDATE 语句。 2 1 0.098