Позиция условий фильтрации "INNER JOIN" в запросе; Предложение `ON` или` WHERE`

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

Этот вопрос, который отмечен как дубликат для первого, но на самом деле это не то, о чем я хочу спросить.. и как он говорит в бит

Этот вопрос задан раньше и уже имеет ответ. Если эти ответы не полностью отражают ваш вопрос, задайте новый вопрос.

Итак, я задаю новый вопрос.

Я могу написать запрос как:

SELECT *
  FROM customer_order co
  JOIN customer c 
    ON c.id = co.customer_id
   AND c.type = 'special'
  JOIN order o
    ON o.id = co.order_id
   AND o.status = 'dispatched'

ИЛИ

SELECT *
  FROM customer_order co
  JOIN customer c 
    ON c.id = co.customer_id
  JOIN order o
    ON o.id = co.order_id
 WHERE c.type = 'special'
   AND o.status = 'dispatched'

Я абсолютно предпочитаю первый способ, особенно в более сложных запросах, поскольку он группирует условия с таблицами, на которых они работают, что упрощает чтение и определение соответствующих составных индексов. Это также означает, что если я хочу перейти на LEFT JOIN (или, может быть, RIGHT JOIN, я действительно не использую RIGHT JOIN), все условия находятся в нужном месте.

Кажется, есть предпочтение, однако, в сообществе по второму пути.

Кто-нибудь знает, обосновано ли это предпочтение, возможно, в какой-то проблеме с производительностью или в какой-то проблеме с читабельностью, с которой мне еще предстоит споткнуться? Или я могу продолжать быть повстанцем с радостью?

Ответ 1

Они оба одинаковы. Единственным решающим фактором являются стандарты, которые вы используете в своем проекте. Вам нужно решить, что более читаемо для вас, и пойти с этим. Например, способ форматирования ваших запросов - это не то, что я сделал бы.

Я бы сделал

SELECT 
  *
FROM 
  customer_order co

  INNER JOIN customer c ON 
    c.id = co.customer_id AND 
    c.type = 'special'

  INNER JOIN order o ON 
    o.id = co.order_id AND 
    o.status = 'dispatched'

Нет разницы между моим и вашим, за исключением того, что я чувствую, что моя более читаема. Как правило, я обычно резервирую предложение where для операторов, относящихся к базовой таблице. Также первый столбец во внутреннем соединении будет связан с соединенной таблицей (например, o.id или c.id). Это все, что я использую, чтобы просто поддерживать последовательность. Другой разработчик может предпочесть иметь все условные условия в предложении where. Это просто предпочтение

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

Продолжайте то, что вы делаете, но убедитесь, что оно последовательное!

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

Ответ 2

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

Также, как вы сказали, стоит отметить, что при замене внутреннего соединения на левое и правое соединения уравнения меняются, и вам нужны фильтры в 'ON'.