2017-07-26 49 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)