Оптимизированный запрос для получения идентификаторов, отсутствующих в других таблицах

#sql #oracle #oracle11g #subquery #query-optimization

#sql #Oracle #oracle11g #подзапрос #оптимизация запроса

Вопрос:

У меня есть три таблицы. T1 является основным и хранит уникальный идентификатор. Я хочу получить идентификаторы, которых нет в t2 и t3, но которые есть в t1, я написал запрос. Не уверен, что он правильный и оптимизирует один. Нужна помощь, чтобы написать запрос лучшим способом, чем этот, поскольку во всех таблицах содержится огромный объем данных.

 Select t1.ID 
  from t1 
 where ID not in ( 
                  Select distinct t2.ID from t2
                   Union
                  Select distinct t3.ID from t3
                 )
   and col2 ='A'
  

Комментарии:

1. Это больше касается плана выполнения и зависит от вашего распределения данных и мощности всех 3 таблиц. Обычно для всех огромных таблиц лучше использовать 2 hash join anti , поэтому обычно not exists , not in и left join x where x.id is null лучше, чем операторы set (преобразование set в join было отключено по умолчанию, и оно включено по умолчанию только в последних версиях Oracle)

2. Покажите нам результаты 3 следующих запросов: 1. Select count(*), count(distinct ID) from t1 where col2 ='A' 2) select count(*), count(distinct ID) from t2 3) select count(*), count(distinct ID) from t3

Ответ №1:

Я бы использовал not exists :

 select t1.*
from t1
where
    col2 = 'A'
    and not exists(select 1 from t2 where t2.id = t1.id)
    and not exists(select 1 from t3 where t3.id = t1.id)
  

Этот запрос должен использовать следующие индексы:

 t1(col2, id)
t2(id)
t3(id)
  

Ответ №2:

Используйте только операторы set:

 SELECT t1.id
  FROM t1
 WHERE t1.col2 = 'A'
MINUS
(SELECT t2.id FROM t2
 UNION
 SELECT t3.id FROM t3
);