Как JOIN работает в MySQL? - PullRequest
       28

Как JOIN работает в MySQL?

1 голос
/ 11 ноября 2011

Хотя заголовок вопроса дублирует многие обсуждения, я не нашел ответа на этот вопрос:

Рассмотрим простое объединение для нормализованных таблиц тегов как

SELECT tags.tag
FROM tags
    INNER JOIN tag_map
    ON tags.tag_id=tag_map.tag_id
WHERE article_id=xx

Имеет JOIN работать со всеми таблицами тегов и tag_map, затем фильтровать созданную (JOIN ed) таблицу, чтобы найти строки с предложением WHERE для идентификатора статьи

ИЛИ JOIN будет объединять только строки tag_mapтаблица, в которой article_id = xx?

Последний метод должен быть намного быстрее!

Ответы [ 5 ]

1 голос
/ 11 ноября 2011

Зависит от двигателя. Более ранние версии многих механизмов баз данных сначала генерировали бы результаты объединения, а затем фильтровали. Более новые версии двигателей генерируют план выполнения, который достигает самых быстрых результатов. Тест должен был быть выполнен с механизмом БД, проверяющим планы выполнения для вашей версии / базы данных, чтобы найти «что лучше»

1 голос
/ 11 ноября 2011

Предполагая, что это простое или внутреннее объединение:

Ответ таков: в реляционной модели первый ответ верен, он создает таблицу, содержащую каждую строку из первой, пересеченную с каждой строкой из второй таблицы, поэтомуесли у вас N строк в первой и M во второй, он создаст таблицу с NxM, а затем исключит те, где условия не совпадают.

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

В случае MYSQL (только что заметилтег) вы можете использовать следующий синтаксис:

  EXPLAIN [EXTENDED] SELECT select_options

, как объяснено здесь , и MYSQL расскажет вам, как он будет выполнять такой запрос.Это быстрее, чем читать документацию.

1 голос
/ 11 ноября 2011

Это будет первым, насколько мне известно, ГДЕ явно выполняются в результирующей таблице JOINed. (Отказ от ответственности: MySQL может оптимизировать это в некоторых случаях, я не знаю).

Чтобы принудительно включить последнее поведение и выполнить сначала WHERE, вы можете добавить дополнительный фильтр в оператор JOIN ON:

SELECT tags.tag 
    FROM tags 
    INNER JOIN tag_map 
        ON tags.article_id=xx
        AND tags.tag_id=tag_map.tag_id 
    WHERE article_id=xx
1 голос
/ 11 ноября 2011

Объединения работают ТОЛЬКО с теми записями, которые определены в условии WHERE первой таблицы, возвращающей записи. Тем не менее, вы выполняете объединение с tag_map, но ваше предложение where не указывает, с каким псевдонимом связан «Article_ID» , Как правило, лучше всегда указывать в ваших полях либо имя таблицы, либо псевдоним, из которого они получены.

Итак, если article_id исходит из TAGS, то он сначала будет рассматривать этот список как основной набор записей и оптимизировать его с помощью индекса, если таковой существует, и возвращать небольшой набор. После этого соединение применяется к tag_map и будет захватывать все записи, которые соответствуют условию объединения «ON».

Просто чтобы кое-что прояснить. Если бы JOIN был применен ПЕРВЫЙ, до оптимизации предложения WHERE, запросы выполнялись бы вечно. Объединение в основном ПОДГОТОВЛЯЕТ отношения до того, как фактически произойдет выбор записи. Следовательно, план выполнения, который показывает индексы, которые будут использоваться.

1 голос
/ 11 ноября 2011

Вы всегда можете проверить План выполнения , чтобы увидеть, как ваш запрос выполняется шаг за шагом. В MySQL я не знаю, может ли он быть представлен графически с помощью каких-либо сторонних инструментов (как вы можете на MS SQL из коробки с Management Studio), но вы все равно можете проверить это с помощью языковых конструкций explain. Проверьте документацию.

Не зная схемы вашей таблицы

Если article_id относится к таблице tags, то tag_map таблица вообще не сканируется, если столбец соединения в таблице FK не может быть пустым.

Если article_id проиндексирован (т. Е. Первичный ключ), то индекс сканируется ...

и т.д ...

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

...