Это позволяет избежать двойного поиска
Ваш индекс (external_id, external_type, type)
, но для получения всей информации, необходимой для запроса, ему нужно будет использовать этот индекс для поиска строк, а затем использовать id
, который автоматически включается в конце этого индекса для поиска столбцов created_at
и updated_at
в основной таблице.
Оптимизатор делает вывод, что проще было бы перейти прямо кглавная таблица для начала, и поэтому игнорирует индекс.
Вы можете увидеть подтверждение этого факта с помощью вашего утверждения:
Если я изменю первую строку оператора SELECT наудалить users.created_at, users.updated_at, он использует индекс
Как только вы удалите эти столбцы, ему больше не придется выполнять двойной поиск для выполнения запроса. Единственный поиск по индексу - это то, что заставляет его выбрать использование этого индекса.
Что касается следующего:
Если я изменю предложение WHERE для добавления запроса и users.type= «Бла», он использует индекс
Я бы предположил, что оптимизатор теперь считает, что двойной поиск того стоит, если он может достаточно уменьшить строки с помощью этого более избирательного запроса. Понимание причин оптимизатора не всегда легко, но это кажется наиболее очевидной причиной.
Решение
Чтобы заставить его использовать индекс, вам просто нужно сделать так, чтобы он нене нужно выполнять двойной поиск, делая его индексом покрытия.
(external_id, external_type, type, created_at, updated_at)
Этот индекс позволит избежать двойного поиска, поскольку он может фильтровать по первым столбцам, а затем просто использовать оставшиесястолбцы в индексе для удовлетворения SELECT для этой таблицы без необходимости возврата к основной таблице.