Сначала измените
where ((ifnull(c.active,0) = 1)
and isnull(b.Result)
and isnull(b.ResultID))
до
WHERE c.active = 1
AND b.Result IS NULL
AND b.ResultID IS NULL
Я сомневаюсь, что Оптимизатор хорошо справляется с IFNULL()
.
Пожалуйста, укажите SHOW CREATE TABLE
и EXPLAIN SELECT...
Теперь вы, вероятно, увидите, что c
- это первая таблица в EXPLAIN
. Давайте поможем оптимизатору, предоставив
c: INDEX(active, col1) -- in that order
После этого
a: INDEX(col1)
d: INDEX(Id) -- unless it is already PRIMARY KEY(Id)
b: INDEX(IsMatched, table2Id, SelectionId) -- in any order
При работе с JOIN
вам необходимо выяснить, в каком порядке будут просматриваться таблицы. Не доверяйте EXPLAIN
, потому что он (изначально) не знает, какие индексы вы собираетесь добавить.
В вашем случае WHERE
ссылаются на c
и b
. Но b
- это LEFT JOIN
, поэтому мы не можем его использовать. Это оставляет c
. Единственный полезный столбец для индекса - это active
(после переформулирования). Но это звучит как простой, малозначительный «флаг», который Оптимизатор будет избегать. Я добавил что-то в индекс в надежде, что оптимизатор будет обманут.
Итак, какой будет «следующая» таблица? JOINs
получают от c
только до a
. Так что a
следующий. И JOIN
использует col1
.
Далее может быть либо d
, либо b
. Похоже, что "Оптимизатор мог бы делать их в любом порядке и оптимизировать все одинаково независимо от порядка.
d
: Id
это как добраться до него.
b
нужно 3 вещи в ON
, чтобы проверить с помощью простого AND
. Таким образом, «составной» индекс этих 3 столбцов, в любом порядке. (Нет, «кардинальность» каждого столбца не имеет значения, даже для выбора заказа.)
Что касается тестов b... IS NULL
в предложении WHERE
- они, по-видимому, проверяют, не нашел ли LEFT
строку. (Обычно проверяется только PK, поэтому я не знаю, проверяете ли вы также что-то еще.)
Еще одна оптимизация ... Иногда полезно построить индекс "покрытия". Это INDEX
, который содержит все столбцы (для таблицы), упомянутые в любом месте в SELECT
. Это не кажется практичным, поскольку в каждом из 4 случаев будет задействовано множество столбцов.