powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Как избавиться от MERGE JOIN CARTESIAN
25 сообщений из 29, страница 1 из 2
Как избавиться от MERGE JOIN CARTESIAN
    #39250034
nata44845
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть подзпарос такого типа

SELECT X FROM DB1_TRANSFER_A1
WHERE
(DEPT IN('900000000000437A','900000000000436E','90000000000040DF','9000000000004372'))
AND (PRODUCT IN(SELECT T40044916.PRODUCT as P40049295 FROM TMP_PRODUCT_LIST T40044916))
AND (PARTY IN(SELECT T40044917.PARTY as P40049296 FROM TMP_PARTY_LIST T40044917))

Две последние таблицы темповые, и без индексов, но сейчас речь не об этом.

План следующий

| 1 | NESTED LOOPS | | | | | |
| 2 | NESTED LOOPS | | 1 | 51 | 8 (13)| 00:00:01 |
| 3 | MERGE JOIN CARTESIAN | | 1 | 12 | 5 (20)| 00:00:01 |
| 4 | SORT UNIQUE | | 1 | 6 | 2 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL | TMP_PARTY_LIST | 1 | 6 | 2 (0)| 00:00:01 |
| 6 | BUFFER SORT | | 1 | 6 | 3 (34)| 00:00:01 |
| 7 | SORT UNIQUE | | 1 | 6 | 2 (0)| 00:00:01 |
| 8 | TABLE ACCESS FULL | TMP_PRODUCT_LIST | 1 | 6 | 2 (0)| 00:00:01 |
|* 9 | INDEX RANGE SCAN | DB1_TRANSFER_A1_BY_PARTY | 1 | | 2 (0)| 00:00:01 |
|* 10 | TABLE ACCESS BY INDEX ROWID| DB1_TRANSFER_A1 | 1 | 39 | 3 (0)| 00:00:01 |

То есть оптимизатор перемножает между собой две темповые таблицы, друг с другом совсем не связанные, одна из которых может быть и 5 миллионов, а вторая порядка 1000 или больше, а потом из всего этого выбирает.
В результате полный запрос может выполняться 20 часов.

301 NESTED LOOPS (cr=2670751934 pr=2135 pw=11755 time=37606200 us)
2420700469 NESTED LOOPS (cr=260164832 pr=1379 pw=11755 time=1652934272 us cost=7 size=51 card=1)
149093213 MERGE JOIN CARTESIAN (cr=37783 pr=1350 pw=11755 time=68828528 us cost=5 size=12 card=1)
127105 SORT UNIQUE (cr=37775 pr=1350 pw=11755 time=696514 us cost=2 size=6 card=1)
5965168 TABLE ACCESS FULL TMP_PARTY_LIST (cr=37775 pr=0 pw=0 time=1978618 us cost=2 size=6 card=1)
149093213 BUFFER SORT (cr=8 pr=0 pw=0 time=46564896 us cost=3 size=6 card=1)
1173 SORT UNIQUE (cr=8 pr=0 pw=0 time=117 us cost=2 size=6 card=1)
1173 TABLE ACCESS FULL TMP_PRODUCT_LIST (cr=8 pr=0 pw=0 time=117 us cost=2 size=6 card=1)
2420700469 INDEX RANGE SCAN DB1_TRANSFER_A1_BY_PRODUCT (cr=260127049 pr=29 pw=0 time=693975872 us cost=2 size=0 card=52)(object id 1703212)
301 TABLE ACCESS BY INDEX ROWID DB1_TRANSFER_A1 (cr=2412882726 pr=756 pw=0 time=0 us cost=2 size=39 card=1)

Для примера подняла ту же БД на тестовом сервере, и вот там он делает все красиво, сначала MERGE JOIN SEMI
DB1_TRANSFER_A1 и TMP_PRODUCT_LIST, а потом уже умножение результата на TMP_PARTY_LIST.

Как оптимизатору сказать, чтоб не умничал.
Параметры оптимизатора специально сравнивала - одинаковые, версия на главном сервере Enterprise, специально сейчас проверила на двух Standart - план получается такой же.
Через JOIN пробовала переделать, то же самое, я в догадках.
...
Рейтинг: 0 / 0
Как избавиться от MERGE JOIN CARTESIAN
    #39250039
nata44845,

покажи, как именно через джойн переделывала...
...
Рейтинг: 0 / 0
Как избавиться от MERGE JOIN CARTESIAN
    #39250055
nata44845
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SELECT X FROM DB1_TRANSFER_A1 DBTA
JOIN TMP_PRODUCT_LIST T40044916 ON DBTA.PRODUCT=T40044916.PRODUCT
JOIN TMP_PARTY_LIST T40044917 ON DBTA.PARTY=T40044917.PRODUCT
WHERE
(DEPT IN('90000000000006D0','9000000000001D13','900000000000114F','900000000000279E'))

| 0 | SELECT STATEMENT | | 1 | 51 | 8 (13)| 00:00:01 |
| 1 | HASH UNIQUE | | 1 | 51 | 8 (13)| 00:00:01 |
| 2 | NESTED LOOPS | | | | | |
| 3 | NESTED LOOPS | | 1 | 51 | 7 (0)| 00:00:01 |
| 4 | MERGE JOIN CARTESIAN | | 1 | 12 | 4 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL | TMP_PRODUCT_LIST | 1 | 6 | 2 (0)| 00:00:01 |
| 6 | BUFFER SORT | | 1 | 6 | 2 (0)| 00:00:01 |
| 7 | TABLE ACCESS FULL | TMP_PARTY_LIST | 1 | 6 | 2 (0)| 00:00:01 |
|* 8 | INDEX RANGE SCAN | DB1_TRANSFER_A1_BY_PARTY | 1 | | 2 (0)| 00:00:01 |
|* 9 | TABLE ACCESS BY INDEX ROWID| DB1_TRANSFER_A1 | 1 | 39 | 3 (0)| 00:00:01 |


пардон, до этого в плане верхнюю строчку пропустила, повторю план

| 0 | SELECT STATEMENT | | 1 | 51 | 8 (13)| 00:00:01 |
| 1 | NESTED LOOPS | | | | | |
| 2 | NESTED LOOPS | | 1 | 51 | 8 (13)| 00:00:01 |
| 3 | MERGE JOIN CARTESIAN | | 1 | 12 | 5 (20)| 00:00:01 |
| 4 | SORT UNIQUE | | 1 | 6 | 2 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL | TMP_PARTY_LIST | 1 | 6 | 2 (0)| 00:00:01 |
| 6 | BUFFER SORT | | 1 | 6 | 3 (34)| 00:00:01 |
| 7 | SORT UNIQUE | | 1 | 6 | 2 (0)| 00:00:01 |
| 8 | TABLE ACCESS FULL | TMP_PRODUCT_LIST | 1 | 6 | 2 (0)| 00:00:01 |
|* 9 | INDEX RANGE SCAN | DB1_TRANSFER_A1_BY_PARTY | 1 | | 2 (0)| 00:00:01 |
|* 10 | TABLE ACCESS BY INDEX ROWID| DB1_TRANSFER_A1 | 1 | 39 | 3 (0)| 00:00:01 |
...
Рейтинг: 0 / 0
Как избавиться от MERGE JOIN CARTESIAN
    #39250062
Фотография Fogel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nata44845, перед выполнением джойнового запроса статистику по таблицам собирали?
...
Рейтинг: 0 / 0
Как избавиться от MERGE JOIN CARTESIAN
    #39250069
Фотография Fogel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nata44845Для примера подняла ту же БД на тестовом сервере, и вот там он делает все красиво, сначала MERGE JOIN SEMI
DB1_TRANSFER_A1 и TMP_PRODUCT_LIST, а потом уже умножение результата на TMP_PARTY_LIST.

Как оптимизатору сказать, чтоб не умничал.

Если нужно повторить план тестового сервера, можно попробовать так:
Код: plsql
1.
2.
3.
4.
5.
select * from
(SELECT * FROM DB1_TRANSFER_A1 DBTA, TMP_PRODUCT_LIST T40044916
where  DBTA.PRODUCT=T40044916.PRODUCT
and DBTA.DEPT IN ('90000000000006D0','9000000000001D13','900000000000114F','900000000000279E')) t1, TMP_PARTY_LIST T40044917
WHERE t1.PARTY=T40044917.PRODUCT
...
Рейтинг: 0 / 0
Как избавиться от MERGE JOIN CARTESIAN
    #39250075
nata44845
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На темповых нет индексов. Я их на рабочей не могу создать, на тестовой создавала, чуть ускоряло план 9000 вместо 12000, но он там и так неплохой.

Вот, на не самом большом сервере выполнила подзапрос, предварительно темповые таблички заполнив
DB1_TRANSFER_A1=455144
TMP_PARTY_LIST=105193
TMP_PRODUCT_LIST=141

план стал следующий

| 0 | SELECT STATEMENT | | 42 | 2142 | 948 (1)| 00:00:12 |
|* 1 | HASH JOIN SEMI | | 42 | 2142 | 948 (1)| 00:00:12 |
| 2 | NESTED LOOPS | | | | | |
| 3 | NESTED LOOPS | | 934 | 42030 | 855 (1)| 00:00:11 |
| 4 | SORT UNIQUE | | 141 | 846 | 2 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL | TMP_PRODUCT_LIST | 141 | 846 | 2 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | DB1_TRANSFER_A1_BY_PRODUCT | 11 | | 2 (0)| 00:00:01 |
|* 7 | TABLE ACCESS BY INDEX ROWID| DB1_TRANSFER_A1 | 7 | 273 | 12 (0)| 00:00:01 |
| 8 | TABLE ACCESS FULL | TMP_PARTY_LIST | 11762 | 70572 | 92 (0)| 00:00:02 |

То есть когда у нас данных в табличках достаточно, начинает нормально себя вести, а вот если недостаточно.

А на главном к примеру
DB1_TRANSFER_A1=4867123
TMP_PARTY_LIST=1461347
TMP_PRODUCT_LIST=171
...
Рейтинг: 0 / 0
Как избавиться от MERGE JOIN CARTESIAN
    #39250101
Фотография Fogel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nata44845На темповых нет индексов.
зато на основной DB1_TRANSFER_A1 ведь есть, если правильно понял - вот и стройте запрос, последовательно соединяя, а не одновременно в кучу, выше пример я привёл, по аналогии попробуйте варианты.
...
Рейтинг: 0 / 0
Как избавиться от MERGE JOIN CARTESIAN
    #39250129
Fogelnata44845Для примера подняла ту же БД на тестовом сервере, и вот там он делает все красиво, сначала MERGE JOIN SEMI
DB1_TRANSFER_A1 и TMP_PRODUCT_LIST, а потом уже умножение результата на TMP_PARTY_LIST.

Как оптимизатору сказать, чтоб не умничал.

Если нужно повторить план тестового сервера, можно попробовать так:
Код: plsql
1.
2.
3.
4.
5.
select * from
(SELECT * FROM DB1_TRANSFER_A1 DBTA, TMP_PRODUCT_LIST T40044916
where  DBTA.PRODUCT=T40044916.PRODUCT
and DBTA.DEPT IN ('90000000000006D0','9000000000001D13','900000000000114F','900000000000279E')) t1, TMP_PARTY_LIST T40044917
WHERE t1.PARTY=T40044917.PRODUCT

ты правда думаешь, что в этом случае оптимизатор не сольет представление и не приведёт запрос к исходному виду без online view?
...
Рейтинг: 0 / 0
Как избавиться от MERGE JOIN CARTESIAN
    #39250147
Фотография Fogel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый Э - Эхты правда думаешь, что в этом случае оптимизатор не сольет представление и не приведёт запрос к исходному виду без online view?
думать можно всё, что угодно - надо проверять.
...
Рейтинг: 0 / 0
Как избавиться от MERGE JOIN CARTESIAN
    #39250160
Фотография Fogel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чтобы повысить вероятность "не сливания" сформированного представления, можно вот так сделать:
Код: plsql
1.
2.
3.
4.
5.
6.
with t1 as (SELECT * FROM DB1_TRANSFER_A1 DBTA, TMP_PRODUCT_LIST T40044916
where  DBTA.PRODUCT=T40044916.PRODUCT
and DBTA.DEPT IN ('90000000000006D0','9000000000001D13','900000000000114F','900000000000279E'))
select * from
 t1, TMP_PARTY_LIST T40044917
WHERE t1.PARTY=T40044917.PRODUCT


правда, на больших объёмах c with производительность проседает.
...
Рейтинг: 0 / 0
Как избавиться от MERGE JOIN CARTESIAN
    #39250184
Vint
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Fogel,
проверять тебе еще рано. думалка не отросла.... а оба совета бредовые.

nata44845
укажите хинтами cardinality, хотя бы примерную, для темповых таблиц и покажите план.
...
Рейтинг: 0 / 0
Как избавиться от MERGE JOIN CARTESIAN
    #39250247
Fogelдумать можно всё, что угодно - надо проверять.вот прям анекдот вспомнился про алкаша, обезъяну, банан и бутылку водки. :-)
...
Рейтинг: 0 / 0
Как избавиться от MERGE JOIN CARTESIAN
    #39250581
Фотография --Eugene--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nata44845,

откуда планы берете? - DBMS_XPLAN?
на деле план может существенно отличаться.
попробуйте V$SQL_MONITOR + DBMS_SQLTUNE.REPORT_SQL_MONITOR
...
Рейтинг: 0 / 0
Как избавиться от MERGE JOIN CARTESIAN
    #39250690
Фотография AlexFF__|
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nata44845,

На будущее, если хотите получать что-то конкретное без идиотских прикидов, всегда смотрите и прикладывайте план запроса.
По поводу этого, вам выше уже ответили по поводу кардинальности.
...
Рейтинг: 0 / 0
Как избавиться от MERGE JOIN CARTESIAN
    #39250740
Фотография Shtock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я избавлялся хинтом ordered
...
Рейтинг: 0 / 0
Как избавиться от MERGE JOIN CARTESIAN
    #39250806
nata44845
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shtock,

Ага, мне примерно что-то такое и нужно было, спасибо, проблема в том, что тут перечисления таблиц нет как такового, но я думаю это можно переделать через JOIN и главное попросить разработчика внести изменения.

Я еще видела отключение _optimizer_sortmerge_join_enabled=FALSE, но в 11 оракле не нашла такого параметра, может он тут по другому называется?

Получается, что когда оптимизатору кажется, что у темповых таблиц маленькая кардинальность, то он сначала перемножает темповые, когда я на пустых таблицах на малой базе делала это понятно, что такой план получился, и когда я их заполнила понятно что план поменялся, а вот на большой базе он считает, что по сравнению с главной таблицей они все равно малы и начинает их перемножать (хотя там 5 миллионов на 1000 если первое сообщение глянуть пример)
Я эти планы смотрела и в dbms_xplan, и в sql мониторе (у меня Enterprise) отчетливо видно, что каждый запрос висящий 2 и более часов с таким планом, и даже полная трассировка запроса у меня есть, порядка 7300 секунд, из них 7200 это FETCH, и это отнюдь не вывод в программу, это вот этот подзапрос и выбор из него, работа процессора 99%.

В понедельник попробую, но отключение параметра тоже интересно, тогда не придется ждать разработчиков.
...
Рейтинг: 0 / 0
Как избавиться от MERGE JOIN CARTESIAN
    #39250809
pihel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
nata44845,

в 11 oracle тоже можно отключить cartesian join
Код: plsql
1.
2.
  execute immediate 'alter session set "_optimizer_cartesian_enabled"=false';
  execute immediate 'alter session set "_optimizer_mjc_enabled"=false';
...
Рейтинг: 0 / 0
Как избавиться от MERGE JOIN CARTESIAN
    #39250812
nata44845
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pihel,
Уже теплее, спасибо.
Я о чем-то таком догадывалась, просто я список параметров в ОЕМ смотрела, там часть показывают, а этих нет, может быть скрытые.

А почему их два, второй как я понимаю и есть MERGE JOIN CARTESIAN, а первый?
Или любой отключить и сработает?
...
Рейтинг: 0 / 0
Как избавиться от MERGE JOIN CARTESIAN
    #39250992
nata44845
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ага, сначала отключила 2 параметр, из общего запроса выдрала вот такой текст для этого подзапроса

NESTED LOOPS
NESTED LOOPS
NESTED LOOPS
SORT UNIQUE
TABLE ACCESS FULL TMP_PARTY_LIST
SORT UNIQUE
TABLE ACCESS FULL TMP_PRODUCT_LIST
INDEX RANGE SCAN DB1_TRANSFER_POOL_BY_PRODUCT
TABLE ACCESS BY INDEX ROWID DB1_TRANSFER_POOL

Такое подозрение, что начал перемножать просто через HASH_JOIN, судя по тому что INDEX RANGE SCAN за NESTED LOOPS,
отключила 1 параметр тоже.

Запустила тестовый запрос, результат dbms_xplan.

| 0 | SELECT STATEMENT | | 1 | 51 | 8 (25)| 00:00:01 |
|* 1 | HASH JOIN SEMI | | 1 | 51 | 8 (25)| 00:00:01 |
| 2 | NESTED LOOPS | | | | | |
| 3 | NESTED LOOPS | | 1 | 45 | 5 (20)| 00:00:01 |
| 4 | SORT UNIQUE | | 1 | 6 | 2 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL | TMP_PARTY_LIST | 1 | 6 | 2 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | DB1_TRANSFER_A1_BY_PARTY | 1 | | 2 (0)| 00:00:01 |
|* 7 | TABLE ACCESS BY INDEX ROWID| DB1_TRANSFER_A1 | 1 | 39 | 2 (0)| 00:00:01 |
| 8 | TABLE ACCESS FULL | TMP_PRODUCT_LIST | 1 | 6 | 2 (0)| 00:00:01 |

Запрос сам выполнился за 48 секунд в первый раз за счет чтений с диска, и за 13 секунд во второй, в трассировке план такой

101 HASH JOIN SEMI (cr=584376 pr=4 pw=0 time=300 us cost=8 size=51 card=1)
1959 NESTED LOOPS (cr=584373 pr=4 pw=0 time=617626 us)
328204 NESTED LOOPS (cr=299100 pr=4 pw=0 time=2037545 us cost=5 size=45 card=1)
1462246 SORT UNIQUE (cr=4638 pr=0 pw=0 time=271483 us cost=2 size=6 card=1)
1462246 TABLE ACCESS FULL TMP_PARTY_LIST (cr=4638 pr=0 pw=0 time=184444 us cost=2 size=6 card=1)
328204 INDEX RANGE SCAN DB1_TRANSFER_A1_BY_PARTY (cr=294462 pr=4 pw=0 time=1737 us cost=2 size=0 card=1)(object id 1703213)
1959 TABLE ACCESS BY INDEX ROWID DB1_TRANSFER_A1 (cr=285273 pr=0 pw=0 time=0 us cost=2 size=39 card=1)
173 TABLE ACCESS FULL TMP_PRODUCT_LIST (cr=3 pr=0 pw=0 time=0 us cost=2 size=6 card=1)

Лучше, гораздо лучше. До этого я его побоялась бы запускать, опасаясь уйти в бесконечность.

В полном запросе этот блок такой же, осталось поймать реальный запрос от пользователя, может он тестовые и реальные по разному разбирает.
...
Рейтинг: 0 / 0
Как избавиться от MERGE JOIN CARTESIAN
    #39250993
nata44845
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ага, а через два JOIN план такой...

| 0 | SELECT STATEMENT | | 1 | 51 | 7 (15)| 00:00:01 |
|* 1 | HASH JOIN | | 1 | 51 | 7 (15)| 00:00:01 |
| 2 | NESTED LOOPS | | | | | |
| 3 | NESTED LOOPS | | 1 | 45 | 4 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL | TMP_PRODUCT_LIST | 1 | 6 | 2 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | DB1_TRANSFER_A1_BY_PRODUCT | 52 | | 2 (0)| 00:00:01 |
|* 6 | TABLE ACCESS BY INDEX ROWID| DB1_TRANSFER_A1 | 1 | 39 | 2 (0)| 00:00:01 |
| 7 | TABLE ACCESS FULL | TMP_PARTY_LIST | 1 | 6 | 2 (0)| 00:00:01 |

На продукты умножать было бы правильнее, их там всего 1000 в таблице, разработчика бы...
...
Рейтинг: 0 / 0
Как избавиться от MERGE JOIN CARTESIAN
    #39251700
nata44845
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну что я могу сказать, большинство во таких запросиков где TMP_PARTY_LIST=30-80 тысяч, а TMP_PRODUCT_LIST порядка 80-1000 стали выполняться нормально за 24-39 секунд по сносному плану.

Остался один большой запрос, который выполняется как я понимаю с NESTED_LOOPS на две темповых таблицы, хотя опять же как не могу понять логики. Висит 3 часа уже. Размер TMP_PARTY_LIST 500 тысяч, размер TMP_PRODUCT_LIST пока не поняла когда он туда данные запихал и сколько, в мониторинге за 24 часа нет такой вставки.
Данные из EXPLAIN PLAN FOR

| 11 | NESTED LOOPS | | 1 | 79 | 8 (13)| 00:00:01 |
| 12 | NESTED LOOPS | | 1 | 12 | 5 (20)| 00:00:01 |
| 13 | SORT UNIQUE | | 1 | 6 | 2 (0)| 00:00:01 |
| 14 | TABLE ACCESS FULL | TMP_PARTY_LIST | 1 | 6 | 2 (0)| 00:00:01 |
| 15 | SORT UNIQUE | | 1 | 6 | 2 (0)| 00:00:01 |
| 16 | TABLE ACCESS FULL | TMP_PRODUCT_LIST | 1 | 6 | 2 (0)| 00:00:01 |
|* 17 | TABLE ACCESS BY INDEX ROWID| DB1_TRANSFER | 1 | 67 | 3 (0)| 00:00:01 |

Когда его же переделываешь через JOIN получается

| 12 | NESTED LOOPS | | | | | |
| 13 | NESTED LOOPS | | 1 | 73 | 5 (0)| 00:00:01 |
| 14 | TABLE ACCESS FULL | TMP_PRODUCT_LIST | 1 | 6 | 2 (0)| 00:00:01 |
|* 15 | INDEX RANGE SCAN | DB1_TRANSFER_BY_PRODUCT | 4 | | 3 (0)| 00:00:01 |
|* 16 | TABLE ACCESS BY INDEX ROWID| DB1_TRANSFER | 1 | 67 | 3 (0)| 00:00:01 |
| 17 | TABLE ACCESS FULL | TMP_PARTY_LIST | 1 | 6 | 2 (0)| 00:00:01 |

А вот через ORDERED выходит

|* 11 | HASH JOIN | | 1 | 79 | 388K (2)| 01:17:42 |
|* 12 | HASH JOIN | | 1 | 73 | 388K (2)| 01:17:42 |
|* 13 | TABLE ACCESS FULL | DB1_TRANSFER | 1562 | 102K| 388K (2)| 01:17:42 |
| 14 | TABLE ACCESS FULL | TMP_PRODUCT_LIST | 1 | 6 | 2 (0)| 00:00:01 |
| 15 | TABLE ACCESS FULL | TMP_PARTY_LIST | 1 | 6 | 2 (0)| 00:00:01 |

Что как бы не айс.

MERGE JOIN CARTESIAN отключен.
По второму плану получается только через преобразование запроса...
...
Рейтинг: 0 / 0
Как избавиться от MERGE JOIN CARTESIAN
    #39251707
Фотография --Eugene--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nata44845,

offtop: пожалуйста, пользуйтесь средствами форматирования.
если не ради себя, то ради окружающих
...
Рейтинг: 0 / 0
Как избавиться от MERGE JOIN CARTESIAN
    #39251724
nata44845Ну что я могу сказать, большинство во таких запросиков где TMP_PARTY_LIST=30-80 тысяч, а TMP_PRODUCT_LIST порядка 80-1000 стали выполняться нормально за 24-39 секунд по сносному плану.

Остался один большой запрос, который выполняется как я понимаю с NESTED_LOOPS на две темповых таблицы, хотя опять же как не могу понять логики. Висит 3 часа уже. Размер TMP_PARTY_LIST 500 тысяч, размер TMP_PRODUCT_LIST пока не поняла когда он туда данные запихал и сколько, в мониторинге за 24 часа нет такой вставки.

Данные из EXPLAIN PLAN FOR
Код: sql
1.
2.
3.
4.
5.
6.
7.
|  11 |            NESTED LOOPS                |                       |     1 |    79 |     8  (13)| 00:00:01 |
|  12 |             NESTED LOOPS               |                       |     1 |    12 |     5  (20)| 00:00:01 |
|  13 |              SORT UNIQUE               |                       |     1 |     6 |     2   (0)| 00:00:01 |
|  14 |               TABLE ACCESS FULL        | TMP_PARTY_LIST        |     1 |     6 |     2   (0)| 00:00:01 |
|  15 |              SORT UNIQUE               |                       |     1 |     6 |     2   (0)| 00:00:01 |
|  16 |               TABLE ACCESS FULL        | TMP_PRODUCT_LIST      |     1 |     6 |     2   (0)| 00:00:01 |
|* 17 |             TABLE ACCESS BY INDEX ROWID| DB1_TRANSFER          |     1 |    67 |     3   (0)| 00:00:01 |


Когда его же переделываешь через JOIN получается
Код: sql
1.
2.
3.
4.
5.
6.
|  12 |             NESTED LOOPS                |                         |       |       |            |          |
|  13 |              NESTED LOOPS               |                         |     1 |    73 |     5   (0)| 00:00:01 |
|  14 |               TABLE ACCESS FULL         | TMP_PRODUCT_LIST        |     1 |     6 |     2   (0)| 00:00:01 |
|* 15 |               INDEX RANGE SCAN          | DB1_TRANSFER_BY_PRODUCT |     4 |       |     3   (0)| 00:00:01 |
|* 16 |              TABLE ACCESS BY INDEX ROWID| DB1_TRANSFER            |     1 |    67 |     3   (0)| 00:00:01 |
|  17 |             TABLE ACCESS FULL           | TMP_PARTY_LIST          |     1 |     6 |     2   (0)| 00:00:01 |


А вот через ORDERED выходит
Код: sql
1.
2.
3.
4.
5.
|* 11 |            HASH JOIN                  |                  |     1 |    79 |   388K  (2)| 01:17:42 |
|* 12 |             HASH JOIN                 |                  |     1 |    73 |   388K  (2)| 01:17:42 |
|* 13 |              TABLE ACCESS FULL        | DB1_TRANSFER     |  1562 |   102K|   388K  (2)| 01:17:42 |
|  14 |              TABLE ACCESS FULL        | TMP_PRODUCT_LIST |     1 |     6 |     2   (0)| 00:00:01 |
|  15 |             TABLE ACCESS FULL         | TMP_PARTY_LIST   |     1 |     6 |     2   (0)| 00:00:01 |


Что как бы не айс.

MERGE JOIN CARTESIAN отключен.
По второму плану получается только через преобразование запроса...

вот так ))
...
Рейтинг: 0 / 0
Как избавиться от MERGE JOIN CARTESIAN
    #39251765
nata44845
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
помощник наты, спасибо

На тестовой заполнила временные, с пустыми было MERGE (там не отключен), с полными план красивый.
PRODUCT=141
PARTY=1 000 000
DB1_TRANSFER=11 000 000

Запрос тот же.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
|* 12 |             HASH JOIN SEMI               |                         |   144 | 11376 |   737   (1)| 00:00:09 |
|  13 |              NESTED LOOPS                |                         |       |       |            |          |
|  14 |               NESTED LOOPS               |                         |   144 | 10512 |   642   (1)| 00:00:08 |
|  15 |                SORT UNIQUE               |                         |   141 |   846 |     2   (0)| 00:00:01 |
|  16 |                 TABLE ACCESS FULL        | TMP_PRODUCT_LIST        |   141 |   846 |     2   (0)| 00:00:01 |
|* 17 |                INDEX RANGE SCAN          | DB1_TRANSFER_BY_PRODUCT |     8 |       |     2   (0)| 00:00:01 |
|* 18 |               TABLE ACCESS BY INDEX ROWID| DB1_TRANSFER            |     1 |    67 |     9   (0)| 00:00:01 |
|  19 |              TABLE ACCESS FULL           | TMP_PARTY_LIST          | 17054 |    99K|    94   (0)| 00:00:02 |



На главной
PRODUCT=173
PARTY=1 400 000
DB1_TRANSFER=99 000 000

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
|  11 |            NESTED LOOPS                |                       |     1 |    79 |     8  (13)| 00:00:01 |
|  12 |             NESTED LOOPS               |                       |     1 |    12 |     5  (20)| 00:00:01 |
|  13 |              SORT UNIQUE               |                       |     1 |     6 |     2   (0)| 00:00:01 |
|  14 |               TABLE ACCESS FULL        | TMP_PARTY_LIST        |     1 |     6 |     2   (0)| 00:00:01 |
|  15 |              SORT UNIQUE               |                       |     1 |     6 |     2   (0)| 00:00:01 |
|  16 |               TABLE ACCESS FULL        | TMP_PRODUCT_LIST      |     1 |     6 |     2   (0)| 00:00:01 |
|* 17 |             TABLE ACCESS BY INDEX ROWID| DB1_TRANSFER          |     1 |    67 |     3   (0)| 00:00:01 |
|* 18 |              INDEX RANGE SCAN          | DB1_TRANSFER_BY_PARTY |     1 |       |     3   (0)| 00:00:01 |



То есть он просто MJC заменил... Вот гад...

А вот с заполненными таблицами тот же запрос через JOIN, я в предыдущем сообщении верхнюю строчку забыла.

Код: sql
1.
2.
3.
4.
5.
6.
7.
|* 11 |            HASH JOIN                    |                         |     1 |    79 |     8  (13)| 00:00:01 |
|  12 |             NESTED LOOPS                |                         |       |       |            |          |
|  13 |              NESTED LOOPS               |                         |     1 |    73 |     5   (0)| 00:00:01 |
|  14 |               TABLE ACCESS FULL         | TMP_PRODUCT_LIST        |     1 |     6 |     2   (0)| 00:00:01 |
|* 15 |               INDEX RANGE SCAN          | DB1_TRANSFER_BY_PRODUCT |     4 |       |     3   (0)| 00:00:01 |
|* 16 |              TABLE ACCESS BY INDEX ROWID| DB1_TRANSFER            |     1 |    67 |     3   (0)| 00:00:01 |
|  17 |             TABLE ACCESS FULL           | TMP_PARTY_LIST          |     1 |     6 |     2   (0)| 00:00:01 |



Хорошо конечно, что на JOIN реагировать начал, как бы теперь обойтись без разработчика.
...
Рейтинг: 0 / 0
Как избавиться от MERGE JOIN CARTESIAN
    #39252144
nata44845
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
3. Optimizer Bug (_optimizer_transitivity_retain)

The issue with Optimizer regarding (_optimizer_transitivity_retain) is explained best by Oracle ACE Syed Jaffer:

Начинаю уже вот это подозревать, я у этой сво (лочи) merge отобрала, а он то же самое через nested loops делает, разработчик сказал вигвам, у них запросы автогенерируются, join они добавить не могут.
У льюиса тоже почитала про это, но не совсем поняла, что сия фича делает начиная с 10 версии
https://jonathanlewis.wordpress.com/2006/12/13/cartesian-merge-join/
...
Рейтинг: 0 / 0
25 сообщений из 29, страница 1 из 2
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Как избавиться от MERGE JOIN CARTESIAN
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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