5.2.6 Как MySQL оптимизирует LEFT JOIN
и RIGHT JOIN
Выражение "A LEFT JOIN B
" в MySQL реализовано следующим образом:
- Таблица B устанавливается как зависимая от таблицы A и от всех таблиц,
от которых зависит A.
- Таблица A устанавливается как зависимая ото всех таблиц (кроме B),
которые используются в условии
LEFT JOIN
.
- Все условия
LEFT JOIN
перемещаются в предложение WHERE
.
- Выполняются все стандартные способы оптимизации соединения, за
исключением того, что таблица всегда читается после всех таблиц, от
которых она зависит. Если имеется циклическая зависимость, MySQL
выдаст ошибку.
- Выполняются все стандартные способы оптимизации
WHERE
.
- Если в таблице A имеется строка, соответствующая выражению
WHERE
, но в
таблице B ни одна строка не удовлетворяет условию LEFT JOIN
,
генерируется дополнительная строка B, в которой все значения столбцов
устанавливаются в NULL
.
- Если
LEFT JOIN
используется для поиска тех строк, которые отсутствуют
в некоторой таблице, и в предложении WHERE
выполняется следующая
проверка: column_name IS NULL
, где column_name
- столбец, который
объявлен как NOT NULL
, MySQL пререстанет искать строки (для отдельной
комбинации ключа) после того, как найдет строку, соответствующую
условию LEFT JOIN
.
RIGHT JOIN
реализован аналогично LEFT JOIN
.
При указании жесткого порядка чтения таблиц в LEFT JOIN
и STRAIGHT JOIN
оптимизатор связей (который определяет, в каком порядке
таблицы должны быть связаны) будет выполнять работу намного быстрее, так
как ему потребуется проверять меньшее количество перестановок таблиц.
Обратите внимание: отсюда следует, что если выполняется запрос типа
SELECT * FROM a,b LEFT JOIN c ON (c.key=a.key) LEFT JOIN d (d.key=a.key)
WHERE b.key=d.key
MySQL будет делать полный просмотр таблицы b
, поскольку LEFT JOIN
заставит
его читать эту таблицу перед d
.
В этом случае, чтобы предотвратить полный просмотр таблицы b
, нужно
изменить запрос таким образом:
SELECT * FROM b,a LEFT JOIN c ON (c.key=a.key) LEFT JOIN d (d.key=a.key)
WHERE b.key=d.key