非常慢的oracle select语句

时间:2016-10-08 07:53:26

标签: sql oracle select

我有一个select语句包含数十万个数据,但是执行时间非常慢,需要超过15分钟。是否可以改善此select语句的执行时间。

select a.levelP,
       a.code,
       a.descP,
       (select nvl(SUM(amount),0) from ca_glopen where code = a.code and acc_mth = '2016' ) ocf,
       (select nvl(SUM(amount),0) from ca_glmaintrx where code = a.code and to_char(doc_date,'yyyy') = '2016' and to_char(doc_date,'yyyymm') < '201601') bcf,
       (select nvl(SUM(amount),0) from ca_glmaintrx where jum_amaun > 0 and code = a.code and to_char(doc_date,'yyyymm') = '201601' ) debit,
       (select nvl(SUM(amount),0) from ca_glmaintrx where jum_amaun < 0 and code = a.code and to_char(doc_date,'yyyymm') = '201601' ) credit
from ca_chartAcc a
where a.code is not null
order by to_number(a.code), to_number(levelP)

请帮助我加快查询和结果的速度.TQ

1 个答案:

答案 0 :(得分:0)

您的主要问题是大多数子查询都使用搜索条件中的函数,包括您日期中的一些笨拙函数。通过提供实际日期(一个月的范围通常占总行数的一小部分,因此很可能达到指数),可以更好地翻转并明确限定预期范围。

SELECT Chart.levelP, Chart.code, Chart.descP,
       COALESCE(GL_SUM.ocf, 0),
       COALESCE(Transactions.bcf, 0),
       COALESCE(Transactions.debit, 0),
       COALESCE(Transactions.credit, 0),
FROM ca_ChartAcc Chart
LEFT JOIN (SELECT code, SUM(amount) AS ocf
           FROM ca_GLOpen
           WHERE acc_mth = '2016') GL_Sum
       ON GL_Sum.code = Chart.code
LEFT JOIN (SELECT code, 
                  SUM(amount) AS bcf,
                  SUM(CASE WHEN amount > 0 THEN amount) AS debit,
                  SUM(CASE WHEN amount < 0 THEN amount) AS credit,
           FROM ca_GLMainTrx
           WHERE doc_date >= TO_DATE('2016-01-01')
                 AND doc_date < TO_DATE('2016-02-01')) Transactions
        ON Transactions.code = Chart.code
WHERE Chart.code IS NOT NULL
ORDER BY TO_NUMBER(Chart.code), TO_NUMBER(Chart.levelP)

如果您只需要几个代码,那么将这些值推送到子查询中可能会产生更好的结果(尽管请注意优化器可能会为您执行此操作)。
可以从TO_NUMBER(...)子句中删除对ORDER BY的调用;但是,这取决于值的格式,因为它们的编码方式可能会改变结果的顺序。