Условие внутри соединения или где



есть ли разница (производительность, передовой практики и т. д...) между помещением условия в предложение 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'


что вы предпочитаете (и, возможно, почему)?

469   9  

9 ответов:

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

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

однако, где вы ставите условие имеет огромное значение, если вы используете левые или правые соединения. Например, рассмотрим эти два запроса:

SELECT *
FROM dbo.Customers AS CUS 
LEFT JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerID
WHERE ORD.OrderDate >'20090515'

SELECT *
FROM dbo.Customers AS CUS 
LEFT JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerID
AND ORD.OrderDate >'20090515'

первый даст вам только те записи, которые имеют заказ, датированный позже 15 мая 2009 года, таким образом, Преобразуя левое соединение во внутреннее соединение. Этот во-вторых, даст эти записи плюс любые клиенты без заказов. Набор результатов очень отличается в зависимости от того, где вы ставите условие. (Выберите * если, например, только для целей, вы не должны использовать, конечно, в производственном коде.) Исключение - это когда вы хотите видеть только записи в одной таблице, но не в другой. Затем вы используете предложение where для условия, а не для соединения.

SELECT *
FROM dbo.Customers AS CUS 
LEFT JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerID
WHERE ORD.OrderID is null

большинство продуктов РСУБД оптимизируют оба запроса одинаково. В "настройке производительности SQL" Питера Гулуцана и Труди Пельцер они протестировали несколько марок СУБД и не обнаружили разницы в производительности.

Я предпочитаю держать условия соединения отдельно от условий ограничения запроса.

Если вы используете OUTER JOIN иногда необходимо поставить условия в предложение join.

где будет фильтр после соединения произошло.

фильтр на соединении, чтобы предотвратить добавление строк во время процесса соединения.

Я предпочитаю JOIN для объединения полных таблиц / представлений, а затем использовать WHERE для введения предиката результирующего набора.

Он чувствует себя синтаксически чище.

Я обычно вижу увеличение производительности при фильтрации на соединении. Особенно если вы можете объединить индексированные столбцы для обеих таблиц. Вы должны быть в состоянии сократить логические чтения с большинством запросов, которые делают это тоже, что в среде с большим объемом является гораздо лучшим показателем производительности, чем время выполнения.

Я всегда слегка удивляюсь, когда кто-то показывает их бенчмаркинг SQL, и они выполнили обе версии sproc 50 000 раз в полночь на сервере dev и сравните среднее время.

помещение условия в соединение кажется мне "семантически неправильным", так как это не то, что объединяет"для". Но это очень качественно.

дополнительная проблема: если вы решите переключиться с внутреннего соединения, скажем, на правое соединение, наличие условия внутри соединения может привести к неожиданным результатам.

соединения быстрее, на мой взгляд, когда у вас есть большая таблица. Это действительно не так много разницы, хотя, особенно если вы имеете дело с довольно небольшим столом. Когда я впервые узнал о соединениях, мне сказали, что условия в соединениях точно такие же, как условия предложения where, и что я мог бы использовать их взаимозаменяемо, если предложение where было конкретным о том, в какой таблице выполнять условие.

лучше добавить условие в соединении. Производительность важнее, чем читаемость. Для больших наборов данных это имеет значение.

Comments

    Ничего не найдено.