Предложение MySQL Join против предложения WHERE - PullRequest
15 голосов
/ 12 ноября 2010

Какая разница в предложении, сделанном двумя следующими способами?

SELECT * FROM table1 INNER JOIN table2 ON (
    table2.col1 = table1.col2 AND
    table2.member_id = 4
)

Я сравнил их оба с базовыми запросами и EXPLAIN EXTENDED и не вижу разницы. Мне интересно, обнаружил ли кто-то здесь разницу в более сложной / интенсивной обработке.

SELECT * FROM table1 INNER JOIN table2 ON (
    table2.col1 = table1.col2
)
WHERE table2.member_id = 4

Ответы [ 4 ]

27 голосов
/ 12 ноября 2010

При соединении INNER два подхода дают идентичные результаты и должны давать один и тот же план запроса.

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

Обратите внимание, что может быть разницей, если выиспользуйте внешнее соединение вместо внутреннего соединения.Например, если вы измените INNER на LEFT и условие соединения не выполнится, вы все равно получите строку, если вы использовали первый метод, но она будет отфильтрована, если вы используете второй метод (поскольку NULL не равен 4).

5 голосов
/ 12 ноября 2010

Если вы пытаетесь оптимизировать свои данные и знать их, добавление пункта «STRAIGHT_JOIN» может значительно повысить производительность. У вас есть внутреннее соединение ON ... Итак, просто чтобы подтвердить, вам нужны только записи, в которых соединены table1 и table2, но только для идентификатора элемента table 2 = какое-то значение .. в данном случае 4.

Я бы изменил запрос так, чтобы таблица 2 была основной таблицей выбора, поскольку она имеет явный "member_id", который можно оптимизировать с помощью индекса для ограничения строк, а затем присоединить к таблице 1, например

select STRAIGHT_JOIN
      t1.*
   from
      table2 t2,
      table1 t1
   where 
         t2.member_id = 4
      and t2.col1 = t1.col2

Таким образом, запрос предварительно квалифицирует только записи member_id = 4, а затем совпадет между таблицей 1 и 2. Таким образом, если в таблице 2 было 50 000 записей, а в таблице 1 было 400 000 записей, то первая таблица table2 будет обработана первой. Ограничение ID = 4 еще меньше, и даже меньше, когда присоединено к таблице 1.

Я точно знаю, что прямое соединение работает, так как я реализовал его много раз, имея дело с данными о более чем 14 миллионах записей, соединенных с более чем 15 таблицами поиска, где движок запутался, пытаясь найти для меня критическую таблицу. , Один такой запрос занимал более 24 часов перед зависанием ... Добавление «STRAIGHT_JOIN» и расстановка приоритетов в том, что «первичная» таблица содержала в запросе, отбросило его до окончательного правильного набора результатов менее чем за 2 часа.

0 голосов
/ 12 ноября 2010

С внутренним соединением это почти * не имеет значения;если вы переключитесь на external join, то вся разница в мире.

* Я говорю «почти», потому что оптимизаторы - это причудливые звери, и не исключено, что при некоторых обстоятельствах это можетлучше выполнять работу по оптимизации первого или последнего. не пытайтесь воспользоваться этим поведением.

0 голосов
/ 12 ноября 2010

Нет особой разницы в ситуации, которую вы описываете; в ситуации с несколькими сложными объединениями, я понимаю, что первое является несколько предпочтительным, поскольку оно несколько уменьшит сложность; Тем не менее, это будет небольшая разница. В целом, вы не должны заметить большой разницы в большинстве, если не во всех ситуациях.

...