powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / не работает SUBQUERY_PRUNING с NOT EXISTS
8 сообщений из 8, страница 1 из 1
не работает SUBQUERY_PRUNING с NOT EXISTS
    #39499229
niv76
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет. Помогите добиться нужного плана запроса. Имеем ORACLE 11.2.0.3 (тестировал так же 11.2.0.4 результат тот же) и OEBS апликуха.
Имеется темповая табличка GL_POSTING_INTERIM и табличка GL_BALANCES партиционированная по period_name (много партиций около 10 лет).
В GL_POSTING_INTERIM лежат данные за несколько дней ближе к текущей дате.
Есть запрос который тормозит, поменять его нельзя т.к. встроен в апликуху (но хотелось бы сгенерировать другой план, например с помошью хинтов, и закрепить его с помощью бейслайна за данным запросом).
Вот упрощенная версия запроса (хинт hash_aj мой) :

Код: sql
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.
select PI.*
    from GL_POSTING_INTERIM PI
   where
    not exists
   (select /*+ hash_aj qb_name(sub) */  'X'
            from GL_BALANCES B
           where (((((((B.ledger_id = PI.ledger_id and
                 B.code_combination_id = PI.code_combination_id) and
                 B.currency_code = PI.currency_code) and
                 B.period_name = PI.period_name) and
                 B.actual_flag = PI.actual_flag) and
                 nvl(B.encumbrance_type_id, (-1)) =
                 nvl(PI.encumbrance_type_id, (-1))) and
                 nvl(B.budget_version_id, (-1)) =
                 nvl(PI.budget_version_id, (-1))) and
                 decode(B.translated_flag,
                         '',
                         '-1',
                         'Y',
                         '0',
                         'N',
                         '0',
                         'R',
                         '1',
                         b.translated_flag) =
                 decode(PI.translated_flag,
                         '',
                         '-1',
                         'Y',
                         '0',
                         'N',
                         '0',
                         'R',
                         '1',
                         PI.translated_flag)))



хочу добиться плана с HASH ANTI JOIN, фулсканом двух таблиц только чтобы в таблице GL_BALANCES фулсканились только партиции с PERIOD_NAME которые есть в таблице GL_POSTING_INTERIM (сейчас беруться все партиции):


Код: sql
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.
---------------------------------------------------------------------------------------------------------------
| Id  | Operation                | Name               | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
---------------------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT         |                    |    20 |  3160 |  5768K  (3)| 19:13:44 |       |       |
|   1 |  LOAD TABLE CONVENTIONAL | GL_BALANCES        |       |       |            |          |       |       |
|*  2 |   HASH JOIN ANTI         |                    |    20 |  3160 |  5768K  (3)| 19:13:44 |       |       |
|   3 |    TABLE ACCESS FULL     | GL_POSTING_INTERIM |    20 |  2000 |    29   (0)| 00:00:01 |       |       |
|   4 |    PARTITION LIST ALL    |                    |  2051M|   110G|  5743K  (2)| 19:08:45 |     1 |    51 |
|   5 |     TABLE ACCESS FULL    | GL_BALANCES        |  2051M|   110G|  5743K  (2)| 19:08:45 |     1 |    51 |
---------------------------------------------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$0C6FB14C
   3 - SEL$0C6FB14C / PI@SEL$1
   5 - SEL$0C6FB14C / B@SUB

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

   2 - access("B"."LEDGER_ID"="PI"."LEDGER_ID" AND "B"."CODE_COMBINATION_ID"="PI"."CODE_COMBINATION_ID"
               AND "B"."CURRENCY_CODE"="PI"."CURRENCY_CODE" AND "B"."PERIOD_NAME"="PI"."PERIOD_NAME" AND
              "B"."ACTUAL_FLAG"="PI"."ACTUAL_FLAG" AND NVL("B"."ENCUMBRANCE_TYPE_ID",(-1))=NVL("PI"."ENCUMBRANCE_TYPE
              _ID",(-1)) AND NVL("B"."BUDGET_VERSION_ID",(-1))=NVL("PI"."BUDGET_VERSION_ID",(-1)) AND
              DECODE("B"."TRANSLATED_FLAG",'','-1','Y','0','N','0','R','1',"B"."TRANSLATED_FLAG")=DECODE("PI"."TRANSL
              ATED_FLAG",'','-1','Y','0','N','0','R','1',"PI"."TRANSLATED_FLAG"))



Скрипты на создание таблиц прикрепил.

Помогите добиться нужного плана, плиз. может быть можно как-то заставить работать BLOOM FILTER или SUBQUERY_PRUNING ?
Ворк эраунды тоже приветствуются. Пока из идей есть только добавить на таблицу GL_POSTING_INTERIM CHECK constraint со списком последних актуальных периодов (тогда Оракл берет только партии из этого листа) но эта идея не очень нравиться, т.к. разные пользователи могут работать с разными периодами и иногда брать старые. Была идея сделать партиционирование по PERIOD_NAME GL_POSTING_INTERIM и добиться wise join в надежде что оракл будет видеть что партиции в GL_POSTING_INTERIM пустые и не будет читать соответствующие партиции в GL_BALANCES, но она темповая (партиционирование не поддерживается).
Спасибо.
...
Рейтинг: 0 / 0
не работает SUBQUERY_PRUNING с NOT EXISTS
    #39499231
niv76
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
После публикации не увидел прикрепленный файл, поэтому дубль два.
...
Рейтинг: 0 / 0
не работает SUBQUERY_PRUNING с NOT EXISTS
    #39499243
Alpdrucken
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
а данные из тех партиций, которые ты не хочеш, по-твоему не попадают под условие чтоли
...
Рейтинг: 0 / 0
не работает SUBQUERY_PRUNING с NOT EXISTS
    #39499305
niv76
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Alpdrucken,

там джойн по B.period_name = PI.period_name. Соответственно читать партиции в "B", которых нет в "PI" нет смысла.
...
Рейтинг: 0 / 0
не работает SUBQUERY_PRUNING с NOT EXISTS
    #39499524
Alpdrucken
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Показалось что временная таблица в подзапросе.

Попробуй добавить в подзапрос условие
Код: plsql
1.
and B.period_name in (select period_name  from GL_POSTING_INTERIM)


у меня подхватил одну партицию по которой были все данные в темпе
...
Рейтинг: 0 / 0
не работает SUBQUERY_PRUNING с NOT EXISTS
    #39499575
niv76
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Запрос встроен в апликуху, менять текст нет возможности. Задумка добиться нужно плана и подсунуть его под существующий запрос с помошью бейслайна.
...
Рейтинг: 0 / 0
не работает SUBQUERY_PRUNING с NOT EXISTS
    #39499738
pihel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
niv76,

а NL по уникальному локальному индексу GL_BALANCES_N1 до первого вхождения не быстрей получается?
Судя по плану в GL_POSTING_INTERIM всего 20 строчек.
...
Рейтинг: 0 / 0
не работает SUBQUERY_PRUNING с NOT EXISTS
    #39499983
niv76
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нет, там статистики нет, работает динамический семплинг. Табличка временная. Делал план на пустой таблице.
В реалии там чуть меньше 1млн строк, и в нужной GL_BALANCES 1...20 млн строк в зависимости от дня месяца.
Думаю побить на ежедневные партиции, тогда 1млн будет сравниваться с 1 миллионом, поэтому быстрее будет фулскан + hash_aj. Только лишние партиции не хочется читать.
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / не работает SUBQUERY_PRUNING с NOT EXISTS
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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