Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / For..loop..merge..endloop. План запроса по первой итерации / 12 сообщений из 12, страница 1 из 1
17.05.2018, 14:17
    #39646140
AntonioPermskiy
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
For..loop..merge..endloop. План запроса по первой итерации
Добрый день,

Столкнулся с такой ситуацией:
Скрипт:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
begin
  for i in 
    (select to_date('29.03.2017', 'dd.mm.yyyy') dat from dual
     union all
     select to_date('30.03.2017', 'dd.mm.yyyy') dat from dual) loop

    Merge..using..T.;
    commit;
  end loop;
end;



В подзапросе T
для даты 29 данные есть
для даты 30 данных нет

Чищу системный кеш:
Код: plsql
1.
2.
alter system flush shared_pool;
alter system flush buffer_cache;



Выполняю цикл. Цикл выполнился быстро . Для 29 подольше, для 30 моментально.

Далее меняю порядок дат:
Код: plsql
1.
2.
3.
   select to_date('30.03.2017', 'dd.mm.yyyy') dat from dual
     union all
     select to_date('29.03.2017', 'dd.mm.yyyy') dat from dual



Чищу кеш. Выполняю цикл. Цикл выполняется долго . Долго висит на 29 . Session Browser показывает затянутое выполнение Long Ops и план запроса с Nested Loops, вместо логичного Hash.


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


Если merge вне цикла, то
для даты 29 план запроса содержит Hash
для даты 30 план запроса содержит Nested Loops

Оба выполняются быстро.


Пока найдено такое решение: использовать внутри цикла
Код: plsql
1.
Execute Immediate 'Merge..'



Вопрос.
Есть ли команды, аналогичные
Код: plsql
1.
2.
alter system flush shared_pool;
alter system flush buffer_cache;


для очистки кеша внутри сессии, конкретной схемы(пользователя)?
...
Рейтинг: 0 / 0
17.05.2018, 14:32
    #39646149
Valergrad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
For..loop..merge..endloop. План запроса по первой итерации
AntonioPermskiy,

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


Если дата передается как bind_variable - то да, так и есть. План построится для первого подсмотренного бинда ( bind_peeking ), после чего будет некоторое время использоваться для всех таких запросов. Это время регулируется “_cursor_bind_capture_interval” , по дефолту - 15 минут.
Если подставить дату как константу, а не бинд. переменную - такого не будет.
...
Рейтинг: 0 / 0
17.05.2018, 14:37
    #39646153
Valergrad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
For..loop..merge..endloop. План запроса по первой итерации
AntonioPermskiy
Вопрос.
Есть ли команды, аналогичные
Код: plsql
1.
2.
alter system flush shared_pool;
alter system flush buffer_cache;


для очистки кеша внутри сессии, конкретной схемы(пользователя)?

Планы находятся в общем кэше ( в этом собственно весь смысл их хранения - переиспользование между сессиями), так что чистить кэш "внутри сессии" бессмысленно, что бы вы под этим ни подразумевали.
...
Рейтинг: 0 / 0
17.05.2018, 14:43
    #39646159
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
For..loop..merge..endloop. План запроса по первой итерации
План можно попытаться Hint'ами подсказать оптимизатору
Чистить ради этого кэш совсем не обязательно.
...
Рейтинг: 0 / 0
17.05.2018, 15:02
    #39646171
Valergrad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
For..loop..merge..endloop. План запроса по первой итерации
Leonid KudryavtsevПлан можно попытаться Hint'ами подсказать оптимизатору
Чистить ради этого кэш совсем не обязательно.

Хинты - зло. Уж лучше уж динамик, как сделал автор.
...
Рейтинг: 0 / 0
17.05.2018, 15:06
    #39646176
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
For..loop..merge..endloop. План запроса по первой итерации
На вкус и цвет все фломастеры разные

Можно хинтовать - что является злом
Можно засирать SGA - что тоже зло

Счастья нигде нет. IMHO
...
Рейтинг: 0 / 0
17.05.2018, 15:10
    #39646181
-2-
-2-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
For..loop..merge..endloop. План запроса по первой итерации
ValergradХинты - зло. Уж лучше уж динамик, как сделал автор.Ежехардпарс не гарантирует оптимальности запроса. Сейчас оптимизатор на данную дату корректно определяет кардиналити, потом появились данные вне гистограмм или гистограммы изменились после сбора статистики.
...
Рейтинг: 0 / 0
17.05.2018, 15:22
    #39646189
AntonioPermskiy
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
For..loop..merge..endloop. План запроса по первой итерации
Valergrad,

Спасибо за сообщения.

В merge внутри цикла я просто подставляю i.dat . Бинд это или нет, сходу, не знаю.


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
      MERGE INTO ABC a
              USING (select t1.key0, t1.f0, t2.vv0 v0, t2.vv1 v1
                     from ABC  t1
                     inner join ABC  t2 on t1.key0 = t2.key0 and t1.f0<>t2.f0
                     where t1.dat = i.dat
                       and t2.dat = i.dat
                       and ((t2.vv0 is not null) or (t2.vv1 is not null))
                       and (t1.v0 is null) and (t1.v1 is null)
                    ) tmp
                 ON (
                     a.DAT = i.dat
                     AND a.key0 = tmp.key0
                     AND a.f0 = tmp.f0
                     )
         WHEN MATCHED
         THEN
            UPDATE SET
               a.v0 = tmp.v0,
               a.v1 = tmp.v1;    
...
Рейтинг: 0 / 0
17.05.2018, 15:38
    #39646201
Fogel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
For..loop..merge..endloop. План запроса по первой итерации
AntonioPermskiyВ merge внутри цикла я просто подставляю i.dat . Бинд это или нет, сходу, не знаю.


Код: plsql
1.
2.
3.
4.
5.
...
and ((t2.vv0 is not null) or (t2.vv1 is not null))
and (t1.v0 is null) and (t1.v1 is null)
                    ) tmp
...



это не бинд

и
Код: plsql
1.
2.
3.
4.
5.
..
and coalesce(t2.vv0,t2.vv1) is not null
and coalesce(t1.v0,t1.v1) is null
                    ) tmp
...
...
Рейтинг: 0 / 0
17.05.2018, 15:50
    #39646213
MaximaXXL
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
For..loop..merge..endloop. План запроса по первой итерации
AntonioPermskiy,

на пробу, заменить
Код: plsql
1.
2.
3.
4.
                     from ABC  t1
                     inner join ABC  t2 on t1.key0 = t2.key0 and t1.f0<>t2.f0
                     where t1.dat = i.dat
                       and t2.dat = i.dat


на
Код: plsql
1.
2.
3.
                     from ABC  t1
                     inner join ABC  t2 on (t1.key0 = t2.key0 and t1.f0<>t2.f0 and t1.dat = t2.dat)
                     where t1.dat = i.dat
...
Рейтинг: 0 / 0
17.05.2018, 15:58
    #39646226
Valergrad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
For..loop..merge..endloop. План запроса по первой итерации
FogelAntonioPermskiyВ merge внутри цикла я просто подставляю i.dat . Бинд это или нет, сходу, не знаю.


Код: plsql
1.
2.
3.
4.
5.
...
and ((t2.vv0 is not null) or (t2.vv1 is not null))
and (t1.v0 is null) and (t1.v1 is null)
                    ) tmp
...



это не бинд



А что это если не бинд? Это бинд конечно.
...
Рейтинг: 0 / 0
17.05.2018, 16:00
    #39646231
Valergrad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
For..loop..merge..endloop. План запроса по первой итерации
AntonioPermskiyValergrad,

Спасибо за сообщения.
Бинд это или нет, сходу, не знаю.



Это бинд. Кстати, вы можете это узнать и сами просто посмотрев план запроса. Если смотреть план запроса через dbms_xplan, то с опцией +PEEKED_BINDS вы увидите дополнительную секцию с биндами, в которой вы сможете даже посмотреть какое реально значение забиндовалось ( это и будет соответственно 29-е или 30-е - в зависимости от порядка ).
Если вы им пользуетесь, то он лежит как обычно - в v$sql_plan в xml-е.
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / For..loop..merge..endloop. План запроса по первой итерации / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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