Почему этот запрос приводит к MERGE JOIN CARTESIAN в Oracle?

Вот мой запрос:

select count(*)
from email_prod_junc j
inner join trckd_prod t5 on j.trckd_prod_sk = t5.trckd_prod_sk
inner join prod_brnd b on t5.prod_brnd_sk = b.prod_brnd_sk
inner join email e on j.email_sk = e.email_sk
inner join dm_geography_sales_pos_uniq u on (u.emp_sk = e.emp_sk and u.prod_brnd_sk = b.prod_brnd_sk)

План объяснения гласит:

Декартово объединение между DM_GEOGRAPHY_SALES_POS_UNIQ и EMAIL_PROD_JUNC.

Я не понимаю почему, потому что для каждой таблицы есть условие соединения.

3 ответа

Решение

Я решил это, добавив подсказку ORDERED:

select /*+ ordered */

Я получил информацию отсюда

Если вы укажете таблицы в том порядке, в котором вы хотите их объединить, и воспользуетесь этой подсказкой, Oracle не будет тратить время на поиск оптимального порядка объединения, а просто объединит их, как они упорядочены в предложении FROM.

Не зная ваших показателей и полного плана, трудно сказать, почему это происходит именно так. Мое лучшее предположение - то, что EMAIL_PROD_JUNC и DM_GEOGRAPHY_SALES_POS_UNIQ относительно невелики и что есть индекс для TRCKD_PROD(trckd_prod_sk, prod_brnd_sk). Если это так, то оптимизатор мог решить, что декартово в двух меньших таблицах дешевле, чем двойная фильтрация TRCKD_PROD.

Я бы предположил, что это происходит из-за условия on (x и y) последнего внутреннего соединения. Oracle, вероятно, не знает, как оптимизировать условие нескольких операторов, поэтому выполняет полное объединение, а затем фильтрует результат по условию по факту. Я не очень знаком с планом объяснения Oracle, поэтому я не могу сказать, что с полномочиями

редактировать

Если вы хотите проверить эту гипотезу, вы можете попробовать изменить запрос на:

inner join dm_geography_sales_pos_uniq u on u.emp_sk = e.emp_sk 
where u.prod_brnd_sk = b.prod_brnd_sk

и посмотреть, исключает ли это полное соединение из плана

Другие вопросы по тегам