我在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'))
答案 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