2017-07-26 48 views
1

我有这种自我加入,在oracle数据库上很慢。我已经把所有相关领域的索引。有没有人有如何提高性能的建议?在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')) 
+1

不加入,从1表计数。 –

+0

我有点新bie我不明白 –

+0

查看查询执行计划 – I3rutt

回答

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')) 
+0

如果我做“解释计划”@ mehmet-sahin查询和思考 - 锑锭查询具有完全相同的成本我的查询... mmmmm ... –

+0

我真的不明白... –

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) 
1

性能调优没有像数据卷的详细信息,数据偏差,指数defintions,解释计划等只是猜测。

因此,这里有一些更多的猜测:)

你的驱动表应该是tariffe tNew因为这是你使用顶部的结果集的一个。现在

tNew.validity_date < to_date('2017-6-26','YYYY-MM-DD')) 

,除非tNew.stato_attivo = 'f'是极具选择性你会在表中可以检索大块的所有行(根据记录多远后面走),所以全表扫描将是最抓住这些记录的有效方法。

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

单列索引

“所有有关领域我已经把指数”不会在这里帮助。你可能会得到所有相关列从一个复合索引有些欣喜:

tariffe (stato_attivo , validity_date, idtariffa, dataimport) 

这将是值得的,如果你经常运行此查询建设。

任何其他猜测?子查询保理一次打到主表。如果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)