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

Столкнулся с такой ситуацией:
Скрипт:
Код: 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
For..loop..merge..endloop. План запроса по первой итерации
    #39646149
Valergrad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonioPermskiy,

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


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


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

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

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

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

Счастья нигде нет. IMHO
...
Рейтинг: 0 / 0
For..loop..merge..endloop. План запроса по первой итерации
    #39646181
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ValergradХинты - зло. Уж лучше уж динамик, как сделал автор.Ежехардпарс не гарантирует оптимальности запроса. Сейчас оптимизатор на данную дату корректно определяет кардиналити, потом появились данные вне гистограмм или гистограммы изменились после сбора статистики.
...
Рейтинг: 0 / 0
For..loop..merge..endloop. План запроса по первой итерации
    #39646189
AntonioPermskiy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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
For..loop..merge..endloop. План запроса по первой итерации
    #39646201
Фотография Fogel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
For..loop..merge..endloop. План запроса по первой итерации
    #39646213
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
For..loop..merge..endloop. План запроса по первой итерации
    #39646226
Valergrad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
For..loop..merge..endloop. План запроса по первой итерации
    #39646231
Valergrad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonioPermskiyValergrad,

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



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


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