[英]Oracle Query SQL Tuning?
select round(avg(et_gsm_sınyal)) as sinyal,mahalle_kodu,ilce_kodu,sebeke
from
(select et_gsm_sınyal,sozlesme_no,SUBSTR(et_operator,1,5) as sebeke
from thkol316old
where tarih >= ADD_MONTHS (TRUNC (SYSDATE, 'MM'), -1)
AND tarih < TRUNC(SYSDATE, 'MM')) okuma,
(select sozlesme_no,ilce_kodu,mahalle_kodu from commt020) bilgiler
where okuma.sozlesme_no=bilgiler.sozlesme_no
group by mahalle_kodu,ilce_kodu,sebeke;
这个查询是可行的,但是运行非常慢。
响应时间约为550秒。
我应该怎么做才能更快地执行此查询?
这是执行计划
SELECT STATEMENT 7547
HASH
GROUP BY 7547
FILTER
Filter Predicates
ADD_MONTHS(TRUNC(SYSDATE@!,'fmmm'),-1)
NESTED LOOPS
NESTED LOOPS
7546
TABLE ACCESS
COMMT020 BY GLOBAL INDEX ROWID 3 ROW LOCATION ROW LOCATION`
首先,我将尝试使用普通的表联接,而不是更笨拙的内联视图-联接,我希望以下方法能起作用(我尚未创建表并对其进行尝试):
select round(avg(okuma.et_gsm_sınyal)) as sinyal,
bilgiler.mahalle_kodu,bilgiler.ilce_kodu, SUBSTR(okuma.et_operator,1,5) as sebeke
from thkol316old okuma
inner join commt020 bilgiler on okuma.sozlesme_no=bilgiler.sozlesme_no
where okuma.tarih >= ADD_MONTHS (TRUNC (SYSDATE, 'MM'), -1)
AND okuma.tarih < TRUNC(SYSDATE, 'MM')
group by bilgiler.mahalle_kodu,bilgiler.ilce_kodu, SUBSTR(okuma.et_operator,1,5);
然后,如果情况仍然缓慢:
明显地
没有为表thkol316old索引列tarih
create index tarih_idx on thkol316old (tarih);
然后
analyze table commt020 compute statistics;
analyze table thkol316old compute statistics;
在Oracle中,分析表会产生用于创建查询执行计划的信息。 每次更改表时,您可能还希望对其进行分析。 许多大型系统都按计划进行。
首先,您只需要从COMMT020表中选择几列就不需要BILIGILER内联视图,那么直接从该表中进行选择就可以了:
SELECT ROUND(AVG(et_gsm_s1nyal)) AS sinyal,
mahalle_kodu,ilce_kodu,sebeke
FROM (
SELECT et_gsm_s1nyal,
sozlesme_no,
SUBSTR(et_operator,1,5) AS sebeke
FROM thkol316old
WHERE tarih >= ADD_MONTHS (TRUNC (SYSDATE, 'MM'), -1)
AND tarih < TRUNC(SYSDATE, 'MM')
) okuma, commt020
WHERE okuma.sozlesme_no = commt020.sozlesme_no
GROUP BY mahalle_kodu,ilce_kodu,sebeke
/
然后,让我们使用ANSI连接表达式重写连接。 我更喜欢ANSI联接而不是旧的Oracle风格的联接,因为它们允许将联接条件与过滤条件分开,因此可以更清楚地了解实际情况。 同样,将别名分配给表并清楚指出我们从哪个表中选择哪些列也是一种好方法。
SELECT ROUND(AVG(o.et_gsm_s1nyal)) AS sinyal,
c.mahalle_kodu, c.ilce_kodu, o.sebeke
FROM (
SELECT th.et_gsm_s1nyal,
th.sozlesme_no,
SUBSTR(th.et_operator,1,5) AS sebeke
FROM thkol316old th
WHERE th.tarih >= ADD_MONTHS (TRUNC (SYSDATE, 'MM'), -1)
AND th.tarih < TRUNC(SYSDATE, 'MM')
) okuma o
JOIN commt020 c ON o.sozlesme_no = c.sozlesme_no
GROUP BY c.mahalle_kodu, c.ilce_kodu, o.sebeke
/
现在,可以清楚地看到其余的内联视图也是多余的。 尽管不知道这些表的细节很难说,但是最好“展开”该内联视图并用直接联接替换它:
SELECT ROUND(AVG(th.et_gsm_s1nyal)) AS sinyal,
c.mahalle_kodu,
c.ilce_kodu,
SUBSTR(th.et_operator,1,5) AS sebeke
FROM commt020 c
JOIN thkol316old th ON c.sozlesme_no = th.sozlesme_no
WHERE th.tarih >= ADD_MONTHS (TRUNC (SYSDATE, 'MM'), -1)
AND th.tarih < TRUNC(SYSDATE, 'MM')
GROUP BY c.mahalle_kodu, c.ilce_kodu, SUBSTR(th.et_operator,1,5)
/
不幸的是,优化此查询进一步需要其他信息,例如:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.