powered by simpleCommunicator - 2.0.29     © 2024 Programmizd 02
Map
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Падает производительность при union all в курсоре
28 сообщений из 28, показаны все 2 страниц
Падает производительность при union all в курсоре
    #40114108
disgust
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Возвращаю процедурой курсор, по непонятной причине зависаю при попытке открыть содержимое курсора.
Запуск самого запроса из процедуры работает молниеносно; если выключить любой из двух запросов, сцепляемых через union all, процедура так же отрабатывает быстро.

Структура процедуры:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
procedure p_proc(p_param varchar2,
                outcur  out sys_refcursor) is
begin
  open outcur for
    select *
      from (select * 
              from first_query
             union all
            select * 
              from second_query)
        -- predicate block
     where 1=1;
end;
...
Рейтинг: 0 / 0
Падает производительность при union all в курсоре
    #40114114
SQL*Plus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
disgust,

Приведите реальный текст вашего запроса.
"Дьявол скрывается в деталях".
...
Рейтинг: 0 / 0
Падает производительность при union all в курсоре
    #40114119
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
disgust,

юнион точно с all?

......
stax
...
Рейтинг: 0 / 0
Падает производительность при union all в курсоре
    #40114126
disgust
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вызов процедуры с одним из двух подзапросов curr day / prev days работает отлично. Выполнение запроса целиком с подстановкой параметров также не выявляет никаких проблем, план запроса прекрасный.


Полный код процедуры:
Код: 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.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
procedure p_getUserOnlineSales(p_emp_id varchar2,
                               p_office_id     varchar2,
                               p_date_from   date default trunc(sysdate),
                               p_date_to     date default sysdate + 1,
                               p_price_from  number default null,
                               p_price_to    number default null,
                               p_item_group  typ_item_groups default cast(null as
                                                                          typ_item_groups),
                               p_receipt_num varchar2 default null,
                                   
                               p_page_num  number default 0,
                               p_page_size number default 10,
                               outcur      out sys_refcursor) is
  item_group_cnt number;
  v_op_id number := f_getOPIdByCode(p_office_id);
  v_emp_id number := f_getEmpIdByCodeTimesheet(p_emp_id);
begin
  -- check filters empty
  item_group_cnt := p_item_group.count(); 
  --
  open outcur for
    select *
      from (select -- visible cols
                   si.item_full_name
                 , si.final_price
                 , si.full_price
                 , si.receipt_num
                 , si.receipt_date
                 , si.vendor_code
                 , case when det.br_summary is null and mr.motiv_rate_value is not null then mr.motiv_rate_value
                        when det.br_summary is not null then det.br_summary
                    end personal_bonus_amount
                 , case when det.br_summary is null and mr.motiv_rate_value is not null then 1
                        when det.br_summary is not null then det.cross_sale_kt
                    end personal_bonus_koeff
                 -- service cols
                 , case when det.br_summary is null and mr.motiv_rate_value is not null then 'approximate'
                        when det.br_summary is not null then 'definite'
                    end personal_bonus_type
                 , coalesce(det.sale_stream, mr.sale_stream, 'Не определено') item_group_name
                 , si.operation_type
                 , si.src
                 -- pagination
                 , row_number() over (order by si.receipt_date desc) rn 
              from (-- curr day
                    select b.cost final_price
                         , case when b.discount = 0 then null else b.price
                            end full_price
                         , b.doc_number receipt_num
                         , b.receipt_date receipt_date
                         , i.item_code vendor_code
                         , i.full_name item_full_name
                         , b.subsite code_op
                         , b.operator_id
                         , to_char(b.businessday, 'yyyymm') sale_period
                         , b.oper_type operation_type
                         , 'bill' src
                      from scheme.bills b
                      join scheme.items i on i.item_code = b.item
                     where b.businessday = trunc(p_date_to)
                       and b.subsite = p_office_id
                       and b.operator_id = p_emp_id
                    union all
                    -- prev days
                    select l.txn_amount final_price
                         , case when l.disc = 0 then null else l.price
                             end full_price
                         , t.receipt_num receipt_num
                         , t.ts receipt_date
                         , i.item_code vendor_code
                         , i.full_name item_full_name
                         , s.office_code code_op
                         , e.emp_code operator_id
                         , to_char(l.dt,'yyyymm') sale_period
                         , l.txn_type operation_type
                         , 'txn' src
                      from scheme.txn t
                      join scheme.txn_lines l on t.rtl_txn_id = l.rtl_txn_id
                      join scheme.items i on l.item_id = i.item_id
                      join scheme.offices s on t.subsite_id = s.subsite_id
                      join scheme.employees e on t.employee_id = e.employee_id
                     where t.ts between trunc(p_date_from) and trunc(p_date_to)
                       and t.subsite_id = v_op_id
                       and t.employee_id = v_emp_id
                 ) si
             /* fact */
             left join scheme.sales_details det on si.sale_period = det.period
                                               and si.code_op = det.op_code
                                               and ltrim(si.operator_id,'0') = ltrim(det.tab_num,'0')
                                               and si.receipt_num = det.rcpt_num
                                               and si.vendor_code = det.item_article
             /* prognosis */
             left join scheme.rates mr on si.sale_period = mr.motiv_rate_period
                                      and si.code_op = mr.code_op
                                      and si.vendor_code = mr.code_1c
            where 1 = 1
              and si.final_price between nvl(p_price_from, si.final_price) and nvl(p_price_to, si.final_price)
              /* if no filters */
              and (item_group_cnt = 0 or coalesce(det.sale_stream, mr.sale_stream, 'Не определено') in (select * from table(p_item_group)))
              and si.receipt_num = nvl(p_receipt_num, si.receipt_num)                                        
           )
     where rn between p_page_num * p_page_size + 1 and (p_page_num + 1) * p_page_size;
end; 
...
Рейтинг: 0 / 0
Падает производительность при union all в курсоре
    #40114127
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Методика решения подобных проблем одна: смотрите планы исполнения (dbms_xplan.display_cursor, sql_id найдете в v$session), анализируете.
Если есть tuning pack, то можно воспользоваться SQL Monitor-ом.
На основании раскопанного много думаете и корректируете.
...
Рейтинг: 0 / 0
Падает производительность при union all в курсоре
    #40114128
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
disgust

Код: plsql
1.
     where rn between p_page_num * p_page_size + 1 and (p_page_num + 1) * p_page_size;


ууу....
...
Рейтинг: 0 / 0
Падает производительность при union all в курсоре
    #40114129
disgust
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andrey_anonymous,

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

Очевидно, мне рановато давать советы такому мастеру оптимизации, как Вы.
...
Рейтинг: 0 / 0
Падает производительность при union all в курсоре
    #40114136
disgust
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andrey_anonymous,

Советы давать не рано, но существенного влияния на производительность паждинатор не оказывает.
Фетч курсора виснет вне зависимости от накладывания оконной функции, при этом тесты показывают, что к проблемам приводит юнион, о чём и был задан вопрос.
...
Рейтинг: 0 / 0
Падает производительность при union all в курсоре
    #40114143
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
disgust,

как вариант
по receipt_date есть индекс, c union all он "не используется"

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

Я же говорю - Ваше кунг-фу круче моего.
...
Рейтинг: 0 / 0
Падает производительность при union all в курсоре
    #40114145
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax
как вариант
по receipt_date есть индекс, c union all он "не используется"

Ставлю на сортировку результата объединенного union all множества для нужд "паджинатора".
Но он "влияния не оказывает", так что ТС может продолжать изыскания...
...
Рейтинг: 0 / 0
Падает производительность при union all в курсоре
    #40114148
disgust
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andrey_anonymous

Я же говорю - Ваше кунг-фу круче моего.


Да нет, конечно. offset мне в оракл ещё не подвезли, паджинатор через row_number() не идеален, но справляется.
Но можете и дальше обижаться.

За совет про dbms_xplan.display_cursor спасибо, пока нет возможности воспользоваться, грантов не хватает.
...
Рейтинг: 0 / 0
Падает производительность при union all в курсоре
    #40114150
disgust
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andrey_anonymous,

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

1. Убирать надо оконную функцию.
2. Методику разборок я уже привел - dbms_xplan.display_cursor в помощь, остальное - от лукавого.
...
Рейтинг: 0 / 0
Падает производительность при union all в курсоре
    #40114158
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
disgust

и всё равно непонятно, почему вне процедуры запрос не тормозит.


1) возможно разные параметры оптимизатора, напр first/all rows

2) возможно не все сроки фетчите

3) select count(поля) from ( ... тож за разное время выполняется в процедуре и вне?

4) бинд в процедуре и константы во вне (плюсе)

5) еще что-то

зы
просить ДБА чтоб снял трассу для обоих случаев

.....
stax
...
Рейтинг: 0 / 0
Падает производительность при union all в курсоре
    #40114186
SQL*Plus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous
Stax
как вариант
по receipt_date есть индекс, c union all он "не используется"

Ставлю на сортировку результата объединенного union all множества для нужд "паджинатора".
Но он "влияния не оказывает", так что ТС может продолжать изыскания...

+1
...
Рейтинг: 0 / 0
Падает производительность при union all в курсоре
    #40114187
SQL*Plus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
disgust
andrey_anonymous,

отключённая паджинация никак не повлияла...

"Не верю!" (с) Склихасовский

Сколько всего строк выбирает этот запрос без "паджинации"?
...
Рейтинг: 0 / 0
Падает производительность при union all в курсоре
    #40114196
disgust
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SQL*Plus


Сколько всего строк выбирает этот запрос без "паджинации"?


68, выборка небольшая.
...
Рейтинг: 0 / 0
Падает производительность при union all в курсоре
    #40114207
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дык может и проверить планы с "паджинацией" и без?
...
Рейтинг: 0 / 0
Падает производительность при union all в курсоре
    #40114494
disgust
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
case solved, достучался до админов, получил план оптимизатора при выполнении запроса в процедуре.
оптимизатор каким-то мистическим образом решил начать сканить scheme.sales_details по другому индексу, вылечилось хинтом.

всем спасибо за участие, советы и саркастичные комментарии.
...
Рейтинг: 0 / 0
Падает производительность при union all в курсоре
    #40114523
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
disgust
case solved, достучался до админов, получил план оптимизатора при выполнении запроса в процедуре.
оптимизатор каким-то мистическим образом решил начать сканить scheme.sales_details по другому индексу, вылечилось хинтом.

всем спасибо за участие, советы и саркастичные комментарии.


такой эффект обычно получается на маленьких таблицах при изобилии индексов, подходящих под условие запроса.
Надо либо порядка на четыре - пять увеличить объем данных в таблице scheme.sales_details, либо дропнуть бессмысленные индексы, начиная с самого бессмысленного, или, как-то заменить на осмысленные.
Тогда и без хинтов, скорее всего, все придет в норму.

Когда таблица маленькая, и размеры ключа в индексах отличаются, оптимизатор имеет обыкновение считать,
что для такой таблицы, из всех бессмысленных, но подходящих под условия запроса индексов,
надо просто взять тот, у которого самый короткий ключ. Отсюда возникают хинты.
Кстати, на индексы хинты, исторически, достаточно хрупкие.

Оптимизатор следует им, до тех пор, пока, в процессе своей деятельности, не посчитает их полнейшей дурью.
Правда, обычно, он может хотя бы косвенно объяснить, почему он так подумал.
Например, потому что решил, что раз объем данных возрос, то пора переходить от nested loop join к hash join.

В таких обстоятельствах, с любовью указанный вами индекс, оптимизатором может быть признан за чистый мусор.
Тогда вам придется ему объяснять:
"Дорогой, тебе хеш джойн нельзя, колокольчик в нос вставь и пользуйся нестед лупом с помощью указанного мной индекса".
...
Рейтинг: 0 / 0
Падает производительность при union all в курсоре
    #40114532
disgust
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
booby,

Понятно, что жёстко прибивать гвоздями индекс - не самый хороший вариант.
Сейчас таблица ~24кк строк, прирастает на 3-4кк в месяц.

Вероятно, стоит поубивать все те индексы, которые явно не берутся оптимизатором и попробовать выключить хинт.
...
Рейтинг: 0 / 0
Падает производительность при union all в курсоре
    #40114558
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
disgust,

вы постарайтесь поострожнее обходиться с такими приговорами.

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

Если не знаете, зачем он создавался, и не можете самостоятельно определить правдоподобную версию,
лучше ничего не делать, или, хотя бы спросить у кого-то - "о чём ты думал?".

Убить и посмотреть, кто заплачет - может быть вариантом, но, предпочтительно, не в боевом окружении,
где может прилететь ответка за опрометчивые атакующие действия.
...
Рейтинг: 0 / 0
Падает производительность при union all в курсоре
    #40114601
Фотография AlexFF__|
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby

...
Кстати, на индексы хинты, исторически, достаточно хрупкие.
Оптимизатор следует им, до тех пор, пока, в процессе своей деятельности, не посчитает их полнейшей дурью.
...

Оптимизатор не посчитает их "полнейшей дурью" и будет следовать им всегда, если может их применить .
И откажется только в случае их полной невозможности, например, когда сам же перепишет запрос при преобразованиях в такой вид, где захинтованный индекс в принципе неприменим или другие хинты/настройки оптимизатора помешают.
...
Рейтинг: 0 / 0
Падает производительность при union all в курсоре
    #40114613
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexFF__|,

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

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

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

В простых случаях все просто, и у хинтователя есть много больше прав на претензию, что он умнее оптимизатора.

А в случаях сложных соединения/агрегации множества таблиц, все может становится весьма болезненным с точки зрения
производительности, при попытках оптимизатора следовать за хинтами, по крайней мере хинтами над индексами,
чуждого ему писателя sql, и особенно, если тот писатель не вполне понимает, что делает.
Что, к сожалению, совсем нередко встречается.
...
Рейтинг: 0 / 0
Падает производительность при union all в курсоре
    #40114723
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
booby
если тот писатель не вполне понимает, что делает.
Что, к сожалению, совсем нередко встречается.
именно так. Вообще, хинтование индекса - это просто быстрый воркэраунд, а не полноценное решение проблемы. По-хорошему, надо разбираться с причиной выбора неоптимального плана
...
Рейтинг: 0 / 0
Падает производительность при union all в курсоре
    #40114724
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
реальность всегда состоит из компромиссов.
Когда у общества нет цветовой дифференциации штанов системы некачественные статистики,
межумочные объемы данных и случайное индексирование, ее поведение характеризуется как почти женское, в смысле непредсказуемости, не говоря о вероятных чудесах при обновлении версии системы.

Как-то "вчера поставил хинт, а сегодня убрал, но вчера поставил" приходится с ней общаться.
В общем, это +- околорабочее "взрослое" состояние.

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


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