Есть ли разница (производительность, лучшие практики и т. Д.) Между помещением условия в предложение JOIN и предложением WHERE?
Например...
-- Condition in JOIN
SELECT *
FROM dbo.Customers AS CUS
INNER JOIN dbo.Orders AS ORD
ON CUS.CustomerID = ORD.CustomerID
AND CUS.FirstName = 'John'
-- Condition in WHERE
SELECT *
FROM dbo.Customers AS CUS
INNER JOIN dbo.Orders AS ORD
ON CUS.CustomerID = ORD.CustomerID
WHERE CUS.FirstName = 'John'
Что вы предпочитаете (и, возможно, почему)?
sql
performance
Стив Диньян
источник
источник
FROM Orders JOIN OrderParties ON Orders.Id = OrderParties.Order AND OrderParties.Type = 'Recipient' WHERE Orders.Status = 'Canceled'
Ответы:
Реляционная алгебра допускает взаимозаменяемость предикатов в
WHERE
предложении иINNER JOIN
, таким образом, дажеINNER JOIN
запросы сWHERE
предложениями могут иметь предикаты, переупорядоченные оптимизатором, чтобы они уже могли быть исключены во времяJOIN
процесса.Я рекомендую вам писать запросы наиболее читабельным способом.
Иногда это включает в себя создание
INNER JOIN
относительно «неполных» и включение некоторых критериевWHERE
просто для того, чтобы сделать списки критериев фильтрации более легкими в обслуживании.Например, вместо:
Напишите:
Но это зависит, конечно.
источник
Для внутренних объединений я не заметил заметной разницы (но, как и во всех настройках производительности, вы должны проверить свою базу данных в ваших условиях).
Однако, где вы ставите условие имеет огромное значение, если вы используете левое или правое соединение. Например, рассмотрим эти два запроса:
Первый даст вам только те записи, чей заказ датирован позднее 15 мая 2009 года, и, таким образом, преобразование левого объединения во внутреннее объединение.
Второй даст эти записи плюс любые клиенты без заказов. Набор результатов сильно отличается в зависимости от того, где вы поставили условие. (Выберите * только для примера, конечно, вы не должны использовать это в рабочем коде.)
Исключением является случай, когда вы хотите видеть только записи в одной таблице, но не в другой. Затем вы используете условие where для условия, а не для соединения.
источник
A left join B
каждая строка из A соединяется с каждой соответствующей строкой из B. Если B не имеет строки, которая соответствует, то столбцы A имеют значение, но каждый столбец из B в этой строке отображается как значения NULL. Если вы написали, уwhere B.somecolumn = ‘somevalue’
вас есть NULL (B.somecolumn), который сравнивается с 'somevalue'. Все, что сравнивается с NULL, является ложным, поэтому все ваши строки, в которых нет соответствующей строки B для строки A, исключаются, и результаты, которые вы получаете, совпадают с результатами INNER JOIN, поэтому внешнее соединение стало внутренним.funds
внутренних объединений перспективы на (ances.id = funds.lead_id и investors.is_manual = 'нет') и SELECT funds.id, projects.id ОТfunds
слева присоединиться к представителям перспективы (progress.id = funds.lead_id), где success.is_manual = 'нет'Большинство продуктов RDBMS оптимизируют оба запроса одинаково. В «Настройка производительности SQL» Питера Гулутзана и Труди Пельцер они протестировали несколько брендов RDBMS и не обнаружили различий в производительности.
Я предпочитаю хранить условия соединения отдельно от условий ограничения запросов.
Если вы используете
OUTER JOIN
иногда, необходимо поместить условия в предложение join.источник
WHERE будет фильтровать после того, как произошло СОЕДИНЕНИЕ.
Фильтруйте JOIN, чтобы предотвратить добавление строк во время процесса JOIN.
источник
ON
Я предпочитаю, чтобы JOIN объединял полные таблицы / представления, а затем использовал WHERE для представления предиката результирующего набора.
Это чувствует себя синтаксически чище.
источник
Обычно я вижу увеличение производительности при фильтрации при объединении. Особенно, если вы можете объединить индексированные столбцы для обеих таблиц. Вы должны быть в состоянии сократить количество логических операций чтения с большинством запросов, которые делают это тоже, что в среде с большим объемом является намного лучшим показателем производительности, чем время выполнения.
Я всегда слегка удивлен, когда кто-то показывает свой сравнительный анализ SQL, и он выполнил обе версии sproc 50000 раз в полночь на сервере разработчиков и сравнил среднее время.
источник
Помещение условия в объединение кажется мне «семантически неправильным», поскольку это не то, для чего «соединения» являются «для». Но это очень качественно.
Дополнительная проблема: если вы решите перейти от внутреннего соединения, скажем, к правому соединению, наличие условия внутри JOIN может привести к неожиданным результатам.
источник
По моему мнению, соединения быстрее, когда у вас большой стол. Это действительно не так уж много различий, особенно если вы имеете дело с довольно маленьким столом. Когда я впервые узнал о соединениях, мне сказали, что условия в соединениях аналогичны условиям предложения where и что я могу использовать их взаимозаменяемо, если в предложении where указано, для какой таблицы выполнять условие.
источник
Лучше добавить условие в Join. Производительность важнее, чем удобочитаемость. Для больших наборов данных это имеет значение.
источник