oracle数据库上自联接的性能

oracle数据库上自联接的性能,oracle,performance,oracle11g,query-optimization,self-join,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')

我有一个在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'))
尝试推送PRED提示:

现有版本值得一试:

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 )

没有数据量、数据倾斜、索引定义、解释计划等细节的性能调整只是猜测

下面是更多的猜测:

你的驾驶台应该是tariffe tNew,因为这是你用来在结果集中排名靠前的驾驶台

tNew.validity_date < to_date('2017-6-26','YYYY-MM-DD'))
如果您经常运行此查询,这将是值得构建的

还有其他猜测吗?子查询分解以命中主表一次。如果tariffe有很多列,只进行一次完整表扫描将加快速度

with cte as ( 
       select stato_attivo , validity_date, idtariffa, dataimport
       from tariffe
       where validity_date < to_date('2017-6-26','YYYY-MM-DD'
   )
select count(tNew.idtariffa)  CONT  
from cte tNew 
    join cte tAtt 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) 

不加入,从1个表开始计数。我是一个有点新的bie我不了解查询执行计划如果您刚刚对表进行了大容量加载或大容量插入,对表执行聚集统计。idtariffa字段是主键还是唯一键?如果我解释plan@mehmet sahin查询和Pound stibbons查询的成本与我的查询完全相同…mmmmm。。。
tariffe (stato_attivo , validity_date, idtariffa, dataimport) 
with cte as ( 
       select stato_attivo , validity_date, idtariffa, dataimport
       from tariffe
       where validity_date < to_date('2017-6-26','YYYY-MM-DD'
   )
select count(tNew.idtariffa)  CONT  
from cte tNew 
    join cte tAtt 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)