powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / При дебаге долго отрабатывает простой запрос в теле процедуры
25 сообщений из 28, страница 1 из 2
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968176
jrqq4-h7h2v
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день! Подскажите, в какую сторону копать, в чем может быть причина долгой работы запроса при дебаге.

Сам запрос находится в пакетной функции:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
FUNCTION some_function(pio_error_message  IN OUT NOCOPY VARCHAR2
                      ,po_success_rec_num    OUT NOCOPY NUMBER)
RETURN BOOLEAN
IS
...
    l_pcode  finlog.pcode%TYPE;
...
BEGIN
...
    BEGIN
      SELECT pcode
        INTO l_pcode
        FROM finlog
       WHERE amount_code = 'AC1'
         AND parameter = 'PAR1'
         AND if = 11
         AND dates.get_business_date BETWEEN date_from AND date_to
         AND rownum = 1
       ORDER BY date_from DESC;
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        l_pcode := NULL;
    END;
...
END some_function;



Когда дебажу функцию, ты выполнение занимает порядка 10-15 минут. При этом, перед выполнением данного запроса, меньше чем за секунду выполняется такой же запрос, но с другими параметрами.

Если просто скопировать запрос и выполнить в pl/sql developer-е, то время выполнения около 250 мс.
...
Рейтинг: 0 / 0
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968325
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jrqq4-h7h2v
в чем может быть причина долгой работы запроса
...
выполнение занимает порядка 10-15 минут.
...меньше чем за секунду выполняется такой же запрос, но с другими параметрами .
...
Рейтинг: 0 / 0
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968328
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я бы больше грешил на
jrqq4-h7h2v
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
      SELECT pcode
        INTO l_pcode
        FROM finlog
       WHERE amount_code = 'AC1'
         AND parameter = 'PAR1'
         AND if = 11
         AND dates.get_business_date BETWEEN date_from AND date_to
         AND rownum = 1
       ORDER BY date_from DESC;
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        l_pcode := NULL;
    END;
...
END some_function;


которая наверняка не меняется на протяжении запроса, но каждый раз добросовестно выполняется и пересчитывается
...
Рейтинг: 0 / 0
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968331
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вячеслав Любомудров
но каждый раз добросовестно выполняется и пересчитывается

Сомнительно.
...
Рейтинг: 0 / 0
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968338
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если не объявлена как DETERMINISTIC, то однозначно выполняется больше (или равно), чем отобранных до условия строк
...
Рейтинг: 0 / 0
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968345
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вячеслав Любомудров
однозначно

Вячеслав, а если date_from или date_to - часть access path, тогда как? :)
...
Рейтинг: 0 / 0
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968348
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous,

тогда сам запрос - комбинированная ошибка из Order by и rownum
...
Рейтинг: 0 / 0
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968366
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby
andrey_anonymous,

тогда сам запрос - комбинированная ошибка из Order by и rownum

Это да. Лучше бы вместо rownum воспользовался единственным фетчем курсора, но то такое...
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
FUNCTION some_function(pio_error_message  IN OUT NOCOPY VARCHAR2
                      ,po_success_rec_num    OUT NOCOPY NUMBER)
RETURN BOOLEAN
IS
...
    l_pcode  finlog.pcode%TYPE;
...
BEGIN
...
    declare
      l_business_date date := dates.get_business_date();
    BEGIN
      l_pcode := NULL;
      for i in (
          SELECT pcode
            FROM finlog
           WHERE amount_code = 'AC1'
             AND parameter = 'PAR1'
             AND if = 11
             AND l_business_date BETWEEN date_from AND date_to
           ORDER BY date_from DESC
      ) loop
        l_pcode := i.pcode;
        exit;
      end loop;
    END;
...
END some_function;

...
Рейтинг: 0 / 0
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968372
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous

Вячеслав, а если date_from или date_to - часть access path, тогда как? :)


А тут и нарваться можно:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
set linesize 132
set pagesize 100
drop table tbl purge
/
create table tbl
  as
    select  level from_val,
            level + 10 to_val
      from  dual
      connect by level <= 10
/
drop sequence seq
/
create sequence seq
/
create or replace
  function f1
    return number
    is
    begin
        dbms_output.put_line('F1');
        return seq.nextval;
end;
/
explain plan for
select  *
  from  tbl
  where f1 = from_val
/
select * from table(dbms_xplan.display)
/

PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------
Plan hash value: 2144214008

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |     6 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| TBL  |     1 |     6 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("FROM_VAL"="F1"())

13 rows selected.

set serveroutput on
select  *
  from  tbl
  where f1 = from_val
/

  FROM_VAL     TO_VAL
---------- ----------
         1         11
         2         12
         3         13
         4         14
         5         15
         6         16
         7         17
         8         18
         9         19
        10         20

10 rows selected.

F1
F1
F1
F1
F1
F1
F1
F1
F1
F1
SQL>



А вот с ACCESS:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
set linesize 132
set pagesize 100
drop table tbl purge
/
create table tbl
  as
    select  level from_val,
            level + 10 to_val
      from  dual
      connect by level <= 10
/
drop sequence seq
/
create sequence seq
/
create or replace
  function f1
    return number
    is
    begin
        dbms_output.put_line('F1');
        return seq.nextval;
end;
/
create index tbl_idx
  on tbl(from_val,to_val)
/
explain plan for
select  *
  from  tbl
  where f1 = from_val
/
select * from table(dbms_xplan.display)
/
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------
Plan hash value: 2817369304

----------------------------------------------------------------------------
| Id  | Operation        | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT |         |     1 |     6 |     1   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| TBL_IDX |     1 |     6 |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("FROM_VAL"="F1"())

13 rows selected.

set serveroutput on
select  *
  from  tbl
  where f1 = from_val
/

  FROM_VAL     TO_VAL
---------- ----------
         1         11

F1
SQL>



Т.e UDF + ACCESS без FILTER = баг.

SY.
...
Рейтинг: 0 / 0
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968376
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY
UDF + ACCESS без FILTER = баг.

Видимо стал туговат на старости лет.
Вижу, что заказан доступ по значению 1.
Получена одна строка со значением 1.
Где именно баг?
...
Рейтинг: 0 / 0
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968384
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous
SY
UDF + ACCESS без FILTER = баг.

Где именно баг?


Я бы даже переформулировал: non-deterministic filter без access - суть "магия исходных данных" (с).
Слегка поправил тесткейс с фильтром:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
SQL> 
create table tbl
  as
    select  level from_val,
            level + 10 to_val
      from  dual
      connect by level <= 10
    order by 1 desc
/
 
Table created
create sequence seq
/
 
Sequence created

create or replace
  function f1
    return number
    is
    begin
        dbms_output.put_line('F1');
        return seq.nextval;
end;
/
 
Function created

explain plan for
select  *
  from  tbl
  where f1 = from_val
/
 
Explained
select * from table(dbms_xplan.display)
/
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2144214008
--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |     6 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| TBL  |     1 |     6 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("FROM_VAL"="F1"())
 
13 rows selected

set serveroutput on

select  *
  from  tbl
  where f1 = from_val
/
 
  FROM_VAL     TO_VAL
---------- ----------
 
F1
F1
F1
F1
F1
F1
F1
F1
F1
F1

SQL> 
...
Рейтинг: 0 / 0
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968393
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну как я понимаю eсли non-deterministic в WHERE то ф-ция должна вызываться для каждой строки для котoрой предидушие проверенные условия TRUE. Если нет, то баг ибо потенциально получаем неправильный результат.

SY.
...
Рейтинг: 0 / 0
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968398
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хорошо, а что насчет отсутствия параметра у предполагаемой функции?

Что такое "deterministic" функция без параметра?
Это когда известно, что она всегда 5 возвращает?
Как о таком волшебстве узнает/должна узнавать система?

Наличие/отсутстие параметров и deterministic совершенно перпeндикулярны. Нет параметров не означает ф-ция возврaщает один и тот-же результат. Но начнем с того что это система ничего сама не определяет - юзер говорит системe эта ф-ция deterministic и система ничего не "додумывает" сама.

SY.
...
Рейтинг: 0 / 0
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968408
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
SY,

Количество вызовов функций никак не гарантируется (и для deterministic в том числе - из-за возможных хэш коллизий), просто нужно понимать, что значения в access предикатах - это входные параметры rowsource функции, соответственно, они и вычисляются при её запуске, в отличие от filter предикатов, которые выполняются для каждой из полученных ею строк. Да и вообще, функции - не операторы.
...
Рейтинг: 0 / 0
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968410
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
это я вот к чему: из тех примеров, которые проходили на форуме, следует,
что при наличии параметра не зависящего от фильтруемых данных,
любая функция будет, скорее всего, оптимизирована до единственного вызова.

Случай отсутствия параметра тёмен в двух отношениях - не ясно, какое поведение от системы ожидать,
и, второй момент, в данном случае могут быть проблемы с интерпретацией типа возвращаемого результата.
Третий момент - здесь between, и, вероятно, он разложится в пару вызовов.

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

Как-то так, если дело действительно в этом.
...
Рейтинг: 0 / 0
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968411
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
jrqq4-h7h2v,

Зрите в корень - смотрите на выполнение самого запроса(план, sql monitor, статистики и тд)
...
Рейтинг: 0 / 0
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968413
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
сам запрос-то, предварительно, хорошо бы привести виду, дающему правильный результат.
Потом можно и в корень...
...
Рейтинг: 0 / 0
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968428
jrqq4-h7h2v
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо, за ответы, еще не успел все осмысленно прочитать и проанализировать, возможно уже ответили, и, позже, я все осознаю и пойму ))), но тем не менее, по результатам сегодняшних мытарств, хочу уточнить проблему. Тестирую "some_function":

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
package bla_bla_bla
FUNCTION some_function(pio_error_message  IN OUT NOCOPY VARCHAR2
                      ,po_success_rec_num    OUT NOCOPY NUMBER)
RETURN BOOLEAN
IS
...
    l_pcode  finlog.pcode%TYPE;
...
BEGIN
...
    BEGIN
      SELECT pcode
        INTO l_pcode
        FROM finlog
       WHERE amount_code = 'AC1'
         AND parameter = 'PAR1'
         AND if = 11
         AND dates.get_business_date BETWEEN date_from AND date_to
         AND rownum = 1
       ORDER BY date_from DESC;
    EXCEPTION
      WHEN NO_DATA_FOUND THEN
        l_pcode := NULL;
    END;
...
END some_function;
END bla_bla_bla



1. В тестовом окне pl/sql developer-a, запускаю в режиме дебага (CTRL-R). Ставлю точку останова на запросе в теле функции. Запрос выполняется 15 мин. При этом сама процедура выполняется 30-40 минут.

2. Ничего не меняя, в том же тестовом окне, запускаю выполнение процедуры по F8. Время выполнения всей процедуры 30-40 c.

Если решение проблемы уже описали выше, пожалуйста ткните мордой.

P.S. План выполнения запроса могу предоставить, но, колеги подсказали, что тот план который показывает оракл, при выполнении запроса в отдельном окне, может отличаться от того, который он будет использовать при запуске пакетной процедуры. Если это так, то подскажите, пожалуйста, как можно вытащить реальный план выполнения запроса.
...
Рейтинг: 0 / 0
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968431
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtender

Количество вызовов функций никак не гарантируется (и для deterministic в том числе - из-за возможных хэш коллизий), просто нужно понимать, что значения в access предикатах - это входные параметры rowsource функции, соответственно, они и вычисляются при её запуске, в отличие от filter предикатов, которые выполняются для каждой из полученных ею строк. Да и вообще, функции - не операторы.


А я и не говорю что количество вызовов функций гарантируется. Оптимизатор может, например внaчале cartesian join TABLE_A, TABLE_B и только потом WHERE FUNC = TABLE_B.COL а завтра внaчале WHERE FUNC = TABLE_B.COL a потом join количество вызовов изменится. Баг в том что что оптимизатор решает пофиг что функция non-deterministic у меня тут подходящий индекс завалялся так-что я её выполню разок и хва.

SY.
...
Рейтинг: 0 / 0
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968433
jrqq4-h7h2v
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Друзья, спасибо за участие! Дело было действительно в функции, а что дальше делать и как с этим жить, буду разбираться, слава богу информации накидали много. Еще раз спасибо!
...
Рейтинг: 0 / 0
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968438
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jrqq4-h7h2v,
конкретно в этом случае - получи значение от dates.get_business_date
до запуска запроса и используй переменную привязки.
вот и всё.
...
Рейтинг: 0 / 0
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968445
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
jrqq4-h7h2v
что дальше делать

22149538
...
Рейтинг: 0 / 0
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968457
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous
Вячеслав Любомудров
однозначно

Вячеслав, а если date_from или date_to - часть access path, тогда как? :)
Да, тут неоднозначно
Спасибо за идею на-подумать
...
Рейтинг: 0 / 0
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968665
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY
Баг в том что что оптимизатор решает пофиг что функция non-deterministic у меня тут подходящий индекс завалялся так-что я её выполню разок и хва.

А как должно быть, чтобы не быть багом?
...
Рейтинг: 0 / 0
При дебаге долго отрабатывает простой запрос в теле процедуры
    #39968670
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous

А как должно быть, чтобы не быть багом?


Если ф-ция non-deterministic то только FILTER.

SY.
...
Рейтинг: 0 / 0
25 сообщений из 28, страница 1 из 2
Форумы / Oracle [игнор отключен] [закрыт для гостей] / При дебаге долго отрабатывает простой запрос в теле процедуры
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]