简体   繁体   中英

oracle query fetching very slow

I am trying to run below sql:. But it is not fetching results, is running for more than 5 hours.

SELECT TD.TIME_KEY, CUST.SITE_ID, CUST.NODE, 
       COUNT(CUST.ACCOUNT_NUMBER) AS CUSTOMER_CNT
FROM
TIME_DIM TD INNER JOIN
OSP_ACTIVE_SUB_STAGE CUST ON TIME_KEY BETWEEN CUST.CONNECT_DATE AND (CASE WHEN CUST.CUSTOMER_STATUS_CODE = 'A' THEN SYSDATE ELSE CUST.STATUS_DATE END)
WHERE TD.TIME_KEY >= '01-JAN-14'
GROUP BY TD.TIME_KEY, CUST.SITE_ID, CUST.NODE

Table structure of OSP_ACTIVE_SUB_STAGE:

Name                  Null Type        
--------------------- ---- ----------- 
SITE_ID                    NUMBER(3)   
NODE                       VARCHAR2(5) 
HOUSE_NUMBER               NUMBER(10)  
HOUSE_RESIDENT_NUMBER      NUMBER(10)  
ACCOUNT_NUMBER             NUMBER(10)  
CONNECT_DATE               DATE        
STATUS_DATE                DATE        
CUSTOMER_STATUS_CODE       VARCHAR2(1)

Time_dim is normal time dimension table.

how do i improve and increase the run time of this query or rewrite this query?

Thanks

This is your query:

SELECT TD.TIME_KEY, CUST.SITE_ID, CUST.NODE, COUNT(CUST.ACCOUNT_NUMBER) AS CUSTOMER_CNT
FROM TIME_DIM TD INNER JOIN
     OSP_ACTIVE_SUB_STAGE CUST
     ON TIME_KEY BETWEEN CUST.CONNECT_DATE AND 
        (CASE WHEN CUST.CUSTOMER_STATUS_CODE = 'A' THEN SYSDATE ELSE CUST.STATUS_DATE END)
WHERE TD.TIME_KEY >= '01-JAN-14';
GROUP BY TD.TIME_KEY, CUST.SITE_ID, CUST.NODE

Oy! There is a lot of computation there. You need a different approach. Instead of joining for every day in the period, create a table with connects and ends and then use cumulative sums.

Assuming there is a connect or end on every day for all site/node combinations, you can do:

  select site_id, node, dte, sum(inc) as ActivesOnDate
  from ((select oass.site_id, oass.node, oass.connect_date as dte, 1 as inc
         from osp_active_sub_stage oass
        ) union all
        (select oass.site_id, oass.node,
                (case when oass.customer_status_code = 'A'
                      then trunc(sysdate)
                      else oass.status_date + 1
                 end) , -1 as inc
         from osp_active_sub_stage oass
        )
       )
  group by site_id, node, dte;

This should run a bit faster than the original version.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM