Spec-Zone .ru
спецификации, руководства, описания, API

8.13.16.1. Оптимизация Подзапросов с Преобразованиями Полуобъединения

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

Для внутреннего объединения между двумя таблицами соединение возвращает строку из одной таблицы так много раз, как есть соответствия в другой таблице. Но для некоторых вопросов, единственная информация, которая - вопросы, есть ли соответствие, не число соответствий. Предположите, что есть названные таблицы class и roster те классы списка в программе курса и списках class (студенты зарегистрировались в каждом class), соответственно. Чтобы перечислить классы, которым фактически зарегистрировали студентов, Вы могли использовать это соединение:

SELECT class.class_num, class.class_nameFROM class INNER JOIN rosterWHERE class.class_num = roster.class_num;

Однако, результат перечисляет каждый class однажды для каждого зарегистрированного студента. Для вопроса, который задают, это - ненужное дублирование информации.

Принятие этого class_num первичный ключ в class таблица, двойное подавление могло быть достигнуто при использовании SELECT DISTINCT, но это неэффективно, чтобы генерировать все строки соответствия сначала только, чтобы устранить копии позже.

Тот же самый бездвойной результат может быть получен при использовании подзапроса:

SELECT class_num, class_nameFROM classWHERE class_num IN (SELECT class_num FROM roster);

Здесь, оптимизатор может распознать что IN пункт требует, чтобы подзапрос возвратил только один экземпляр каждого числа class от roster таблица. В этом случае запрос может быть выполнен как полуобъединение — то есть, работа, которая возвращает только один экземпляр каждой строки в class это является соответствующим строками в roster.

Перед MySQL 5.6.6 внешняя спецификация запроса была ограничена простыми сканированиями таблицы или внутренними объединениями, используя синтаксис запятой, и ссылки представления не были возможны. С 5.6.6, внешнее объединение и синтаксис внутреннего объединения разрешается во внешней спецификации запроса, и ограничение, что ссылки на таблицу должны быть базовыми таблицами, было снято.

В MySQL подзапрос должен удовлетворить эти критерии, которые будут обработаны как полуобъединение:

Подзапрос может быть коррелирован или некоррелированый. DISTINCT разрешается, как LIMIT если ORDER BY также используется.

Если подзапрос соответствует предыдущим критериям, MySQL преобразовывает его в полуобъединение и делает выбор на основе издержек из этих стратегий:

Каждая из этих стратегий кроме Двойного Weedout может быть включена или отключила использование optimizer_switch системная переменная. semijoin отметьте средства управления, используются ли полуобъединения. Если это устанавливается в on, firstmatch, loosescan, и materialization флаги включают более прекрасному управлению разрешенными стратегиями полуобъединения. Эти флаги on по умолчанию. См. Раздел 8.8.5.2, "Управляя Переключаемой Оптимизацией".

Использование стратегий полуобъединения обозначается в EXPLAIN вывод следующим образом: