Если вы скрываете столбец внутри «функции» (CONCAT
, DATE
и т. Д.), Никакой индекс не может быть использован для повышения производительности.Это исключает вашу вторую версию из рассмотрения.
С этим связано использование «конструкторов строк» (см. Комментарий a_horse_with_no_name).Исторически они были плохо оптимизированы;избежать их.Я имею в виду WHERE (a,b) IN ( (1,2), ...)
или другие варианты.
Теперь давайте рассмотрим
and table1.id_item = (select max(table2.id_item)
from items table2
where table1.tiers=table2.tiers)
table2
, которым нужно INDEX(tiers, id_item)
в этом порядке.С таким подзапросом очень быстро.Другие подзапросы нуждаются в INDEX(id_item, n_version_item)
Те, что входят в остальное:
and table1.id_item = <<value>>
Теперь давайте посмотрим на все
where (table1.tiers is not null)
and table1.tiers<>''
and table1.id_item = <<value>>
and table1.n_version_item = <<value>>
=
легко оптимизировать;другие нет.Итак, давайте создадим
INDEX(id_item, n_version_item, -- in either order
tiers) -- last
Используя указанный мной порядок, вы также можете избежать необходимости INDEX(id_item, n_version_item)
, который был упомянут выше.
(Это поможет, если вы предоставите SHOW CREATE TABLE
; Iнужно знать, что такое PK, и некоторые другие вещи.)
В качестве бонуса эти индексы будут "покрывающими индексами".
В качестве заключительного примечания (второстепенного):
where (table1.tiers is not null)
and table1.tiers<>''
Было бы лучше выбрать только одну кодировку (NULL
против пустой строки) для того, что вы указываете таким образом.