Oracle查询优化

时间:2015-02-16 10:11:00

标签: sql oracle

我的查询有问题,完成时间超过5分钟。 你能帮我加强它(添加索引,增强查询......) 仅当第二部分包含至少一行时,查询的第一部分才进行更新。 我使用存在来检查这种情况。

2 个答案:

答案 0 :(得分:0)

首先,您应该清理查询。可更新记录必须匹配hasalternativecode $ type_ ='Issuer'和accesspoint_ = 10与EXISTS子句或SET子查询无关。这是表本身的标准,属于WHERE子句。

那么:我猜测GROUP BY条款是一个安全措施吗?您希望每个identifier_和provider_有一条记录,否则需要例外?如果不是这种情况,则删除GROUP BY子句,因为子查询必须只返回一条记录或根本不返回任何记录,而不是更多。

关于优化:人们只能在知道表结构时进行优化。这包括定义(主键,外键,类型,非空列等)和数据(每个表有多少记录;我们多久在表中找到'Issuer'记录,访问点10的频率;多久这两个组合?)。然后,在dbms的执行计划的帮助下,人们可以考虑如何优化。

首先:想想每张桌子有多少记录是相关的。接入点10有多少'发行人'?如果这些事件恰好很少,比如所有记录的2%,那么索引就会有所帮助。那种情况:两列都有索引吗?如果没有,请创建一个。然后转到fi_tradableasset_:您期望查找代码的记录数是多少?再说一次:只有2%?那么:fi_tradableasset_.issuer $ code_上有索引吗?等等。

最后:如果必须读取整个表,则可以始终使用并行提示,例如: UPDATE /*+parallel(prc_alternativecode_,4)*/ prc_alternativecode_ ...。根据机器和使用情况的不同,这可以极大地加快这种说法。

答案 1 :(得分:0)

如果我是你,我会将其转换为MERGE语句,以便删除EXISTS语句的UPDATE子句所需的表的额外访问权限。类似的东西:

merge into table_tgt tgt
using (SELECT   t.issuer$code_,
                a.dateandtime_,
                a.mainentityid_,
                '10' accesspoint_,
                MAX (b.updatoruserid_) updatoruserid_,
                '1423566734151' updatedate_,
                b.provider_ provider$code_,
                'Issuer' || MAX (b.provider_) || MAX (b.identifier_) unicity_,
                MAX (cs.pk_) provider$pk_,
                'false' locked_,
                b.identifier_ alternativecode_
       FROM     table_a a,
                table_b b,
                table_cs cs,
                table_t t
       WHERE    a.accesspoint_ = 100
       AND      a.pk_ = b.cialinstrumentnotification$pk_
       AND      b.provider_ = cs.identifier_ (+)
       AND      b.entitytype_ = 'Issuer'
       AND      a.identifier_ = t.identifier_
       GROUP BY t.issuer$code_,
                a.dateandtime_,
                b.identifier_,
                b.provider_,
                a.mainentityid_)
  on (src.issuer$code_ = tgt.hasalternativecode$code_
      and (tgt.alternativecode_ != src.alternativecode_
           OR tgt.provider$code_ != src.provider$code_)
      AND src.dateandtime_ >= tgt.updatedate_
      and tgt.mainentityid_ = src.mainentityid_)
when matched then
update set tgt.accesspoint_ = src.accesspoint_,
           tgt.updatoruserid_ = src.updatoruserid_,
           tgt.updatedate_ = src.updatedate_,
           tgt.provider$code_ = src.provider$code_,
           tgt.unicity_ = src.unicity_,
           tgt.provider$pk_ = src.provider$pk_,
           tgt.locked_ = src.locked_,
           tgt.alternativecode_ = src.alternativecode_
where      tgt.hasalternativecode$type_ = 'Issuer'
and        tgt.accesspoint_ = 10;

N.B。完全未经测试,因此您应该测试并确保您获得正确的结果。我已经删除了MAX()子句中出现的两列不必要的group by s。我还将ent_codificationsource_表上的连接转换为外连接