在oracle db上进行自联接的性能

时间:2017-07-26 09:41:52

标签: oracle performance oracle11g query-optimization self-join

我在oracle DB上有这个非常慢的自联接。我已将索引放在所有相关领域。有没有人就如何提高性能提出建议?

select count(tNew.idtariffa)  CONT  
    from tariffe tAtt 
    join tariffe tNew on tAtt.idtariffa = tNew.idtariffa 
    where (tAtt.stato_attivo = 't') 
     and (tNew.stato_attivo = 'f') 
     and (tAtt.validity_date < tNew.validity_date) 
     and (tAtt.dataimport < tNew.dataimport) 
     and (tNew.validity_date < to_date('2017-6-26','YYYY-MM-DD'))

3 个答案:

答案 0 :(得分:1)

尝试PUSH_PRED提示:

select /*+ NO_MERGE(tNew) PUSH_PRED(tNew) */
count(tNew.idtariffa)  CONT  
    from tariffe tAtt 
    join tariffe tNew on tAtt.idtariffa = tNew.idtariffa 
    where (tAtt.stato_attivo = 't') 
     and (tNew.stato_attivo = 'f') 
     and (tAtt.validity_date < tNew.validity_date) 
     and (tAtt.dataimport < tNew.dataimport) 
     and (tNew.validity_date < to_date('2017-6-26','YYYY-MM-DD'))

答案 1 :(得分:1)

Exists版本值得尝试:

select count(1) cont
  from tariffe n
  where stato_attivo = 'f'
    and validity_date < date '2017-06-26'
    and exists ( select null
                   from tariffe
                   where idtariffa = n.idtariffa
                     and stato_attivo = 't'
                     and validity_date < n.validity_date
                     and dataimport < n.dataimport )

答案 2 :(得分:1)

没有数据量,数据偏差,索引定义,解释计划等细节的性能调优只是猜测。

所以这里有一些猜测:)

您的驾驶表应该是player->setState(Moving);,因为它是您用来排在结果集之前的那个。

tariffe tNew

现在,除非tNew.validity_date < to_date('2017-6-26','YYYY-MM-DD')) 具有极高的选择性,否则您将检索表中所有行的大部分(取决于记录的返回距离),因此全表扫描将是抓住这些记录的最有效方式。

tNew.stato_attivo = 'f'上的加入存在问题,因为tariffe tAtt不是唯一列。因此,连接是针对一组idtariffa条记录的一组tNew条记录。这些将使用WHERE子句中的条件在内存中进行过滤。

  

&#34;我已将索引放在所有相关领域&#34;

单列索引在这里没有帮助。您可能会从所有相关列的复合索引中获得一些乐趣:

tAtt

如果您经常运行此查询,这将值得建立。

还有其他猜测吗?子查询因子分解到主表一次。如果tariffe (stato_attivo , validity_date, idtariffa, dataimport) 有很多列,那么只进行一次全表扫描会加快速度。

tariffe