2014-10-08 1 views
0

У меня проблема с производительностью в моем запросе, для выполнения которой требуется более 2 минут. В настоящее время основная таблица f_trans имеет 3 миллиона записей.Как заменить определенную пользователем функцию в предложение SELECT?

У меня есть индексированные столбцы в условии where clause и join.

Запрос:

SELECT f.no AS refno, 
       f.v_date AS v_date, 
       (SELECT fnbalance 
            ( 
             f.acnt_code, 
             f.v_date,          
            ) 
        FROM DUAL) AS balance, 

     FROM f_trans f JOIN glr_temp glr 
      ON f.acnt_code = glr.acnt_code 
      AND ftr.v_date >= '24-Aug-2014' 
      AND ftr.v_date <= '27-Aug-2014' 
       JOIN glm_gl_mast glm 
       ON f.acnt_code = glm.acnt_code 
      AND glr.acnt_code = glm.acnt_code; 

функция:

CREATE OR REPLACE function fnbalance ( 
p_glcode in number,p_dtdate in date, 
) 
    return number 
as 
    openbal number; 
    dramt  number; 
    cramt  number; 

begin 

    dramt := 0; 
    cramt := 0; 
    balamt := 0; 
        select nvl (sum (f.dr_amt), 0), nvl (sum (f.cr_amt), 0) 
        into dramt, cramt 
        from ftrans ftr 
        where f.v_source <> 'FFT'  
        and f.acnt_code = p_glcode 
        and ftr.ftr_vou_date < p_dtdate; 

    select nvl((dramt - cramt),0) into balamt from dual; 
    return balamt; 
end 


    Plan hash value: 1037159964 

------------------------------------------------------------------------------------------- 
| Id | Operation    | Name    | Rows | Bytes | Cost (%CPU)| Time  | 
------------------------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT  |     | 53 | 1537 | 23581 (1)| 00:04:43 | 
| 1 | FAST DUAL    |     |  1 |  |  2 (0)| 00:00:01 | 
|* 2 | HASH JOIN    |     | 53 | 1537 | 23581 (1)| 00:04:43 | 
|* 3 | HASH JOIN   |     | 7342 | 73420 | 12 (9)| 00:00:01 | 
| 4 | INDEX FAST FULL SCAN| IND_GLR_ACC  | 5214 | 26070 |  5 (0)| 00:00:01 | 
| 5 | INDEX FAST FULL SCAN| GLM_AC_INDEX  | 7342 | 36710 |  6 (0)| 00:00:01 | 
|* 6 | TABLE ACCESS FULL | F_TRANS | 181K| 3364K| 23568 (1)| 00:04:43 | 
------------------------------------------------------------------------------------------- 

Может помочь мне повторно организовать функцию в пункте выбора?

+0

Выполните следующие действия: 'EXPLAIN PLAN FOR ', а затем 'SELECT * FROM TABLE (DBMS_XPLAN.DISPLAY)' .. Вставьте вывод здесь .. –

ответ

1

И ftr.v_date> = '24 -Aug-2014'
И ftr.v_date < = · 27 -Aug-2014'

Прежде всего, это способ сравнения даты с буквальным слишком плохо. v_date является типом данных DATE, вы должны сравнивать его с датами, а не литералами. Используйте TO_DATE, чтобы преобразовать литерал в дату.

AND ftr.v_date >= TO_DATE('24-Aug-2014', 'DD-Mon-YYYY') 
AND ftr.v_date <= TO_DATE('27-Aug-2014', 'DD-Mon-YYYY') 

Скажи это себе, никогда не полагаться на неявное преобразование данных. Всегда делайте это явно.

И, пожалуйста, разместите план выполнения запроса, чтобы узнать, можно ли улучшить производительность.

Update

Посмотрите, как создать план выполнения в SQL * Plus

SQL> explain plan for select * from dual; 

Explained. 

SQL> select * from table(dbms_xplan.display); 

PLAN_TABLE_OUTPUT 
-------------------------------------------------------------------------------- 
Plan hash value: 272002086 

-------------------------------------------------------------------------- 
| Id | Operation   | Name | Rows | Bytes | Cost (%CPU)| Time  | 
-------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT |  |  1 |  2 |  2 (0)| 00:00:01 | 
| 1 | TABLE ACCESS FULL| DUAL |  1 |  2 |  2 (0)| 00:00:01 | 
-------------------------------------------------------------------------- 

8 rows selected. 

SQL> 

Скопируйте и вставьте план выполнения и разместить его здесь, используя теги кода, чтобы сохранить форматирование.

+0

Спасибо lalit. Я изменил, но проблема все еще сохраняется. – saran

+1

Опубликуйте план выполнения в соответствии с запросом. –

+0

Я не смог добавить свой план в качестве изображения :( – saran