Вложенный запрос или присоединение

Я слышал, что объединение должно быть предпочтительным по отношению к вложенным запросам. Это правда в целом? Или могут быть сценарии, где бы вы были быстрее других:

например. который является более эффективным способом написания запроса?:

Select emp.salary 
from employee emp    
where emp.id = (select s.id from sap s where s.id = 111)

ИЛИ

Select emp.salary     
from employee emp   
INNER JOIN sap s ON emp.id = s.id   
WHERE s.id = 111

Ответ 1

Я слышал, что объединение должно быть предпочтительным по отношению к вложенным запросам. Это правда в целом?

Это зависит от требований и данных.

Использование JOIN предотвращает дублирование информации в наборе результатов для родительской таблицы, если к ней относится несколько дочерних записей, поскольку JOIN возвращает строки, которые соответствуют. Это означает, что если вы хотите использовать уникальные значения из родительской таблицы при использовании JOINs, вам нужно посмотреть на использование предложения DISTINCT или GROUP BY. Но ничто из этого не вызывает беспокойства, если используется подзапрос.

Кроме того, подзапросы не все одинаковы. Там прямая оценка, как и ваш пример:

where emp.id = (select s.id from sap s where s.id = 111)

... и предложение IN:

where emp.id IN (select s.id from sap s where s.id = 111)

..., который будет соответствовать любому из значений (значений), возвращаемых подзапросом, когда прямая оценка выдает ошибку, если s.id возвращает более одного значения. Но там также предложение EXISTS...

WHERE EXISTS(SELECT NULL 
               FROM SAP s
              WHERE emp.id = s.id
                AND s.id = 111)

EXISTS отличается тем, что:

  • предложение SELECT не получает оценку - вы можете изменить его на SELECT 1/0, который должен вызывать ошибку с разделителем на ноль, но не будет
  • возвращает true/false; true, основанный на первом экземпляре, критерии удовлетворяются, поэтому они быстрее работают с дубликатами.
  • в отличие от предложения IN, EXISTS поддерживает одновременное сравнение двух или более сопоставлений столбцов, но некоторые базы данных поддерживают сопоставление кортежей с IN.
  • это более читаемо

Ответ 2

Если запросы логически эквивалентны, оптимизатор запросов должен иметь возможность сделать один и тот же (лучший) план выполнения с каждого из них. В этом случае стиль запроса должен поддерживать то, что может быть понято наилучшим (эти подзапросы для меня).

Ответ 3

Это намного быстрее (и проще писать), чтобы объединить две таблицы в индексе, чем запускать два отдельных запроса (даже подзапрос).