Оптимизатор не знает, что таблица - это простая таблица поиска.Он должен быть готов найти 0 или более 1 строки.
Случай 1: вы знаете , что в каждой из таблиц поиска (JOINed
) ровно 1 строка:
Случай 2. Вы знаете , что в каждой справочной таблице не более 1 строки.
В обоих этих случаях следующий эффективный способ переписать запрос:
SELECT t.a, t.b, ...
( SELECT name FROM LU1 WHERE id = t.name_id ) AS name,
( SELECT foo FROM LU1 WHERE id = t.foo_id ) AS foo,
...
FROM transactions AS t
ORDER BY t.OrderDate
LIMIT ...
и
INDEX(OrderDate)
INDEX(id) -- for each LU table, unless there is already `PRIMARY KEY(id)`
Эта формулировка запроса будет сосредоточена на прохождении ровно 500 строк, отсортированных по OrderDate
, при поиске 12 объектовдля каждой строки.
Это семантически эквивалентно случаю 2 (LEFT JOIN
), поскольку он дает NULL
для name
(и т. д.), когда нет сопоставления.
Технически, случай1 не то же самое.Если поиск не удался, JOIN
не сможет сосчитать строку, но моя переформулировка сохранит строку, показывая NULL
.