tl;dr В этой статье мы рассмотрим случай, когда лучше переместить самый селективный атрибут из префикса составного индекса в суффикс.  А также рассмотрим, что такое pipeline и как с его помощью select-ить данные уже отсортированными.  Есть логгер событий в системе X. Нужно сделать приложение для просмотра данных логов из этой системы. Предполагается, что в системе есть свои коды ошибок и соотвествующие им сообщения. Из них уникальных около 10к. Есть три типа сообщений:  Таблица логов: В таблице 10 миллионов записей. datetime уникален всегда, а вот поле message имеет всего 10к уникальных полей. Для генерации записей сделал процедуру, генерирующую рандомный лог. datetime изменяется так, будто логи записываются раз в секунду. Предполагаем, что самой частой операцией пользователя приложения будет вывод всего лога за конкретную дату.
Лучше всего это сделать через запрос типа Т.е. выбрать все записи за определённую дату с сортировкой по ней же. Причём если в составном индексе дата идёт первой, то её даже сортировать не нужно, она возвращается уже в отсортированном виде.  Explain этого запроса показывает хорошие результаты: Затронуто 172к полей. Это вполне ожидаемый результат при том условии, что данные генерировались так, будто логгер каждую секунду что-то пишет в БД.  Отмечу, что даже если сортировка будет по убыванию (descending), то всё равно данные fetch-ятся уже отсортированными, и их не надо сортировать filesort–ом: Без filesort–а и без temporary. Всё точно также, как и в первом случае.
Сиё явление называют pipeline, за то, что данные хранятся как бы связанными по цепочке, один за другим. И можно вытянуть все значения, начиная как с начального звена (order by asc), так и с конечного (desc).  Чтобы понять, как отсортирован message в составном индексе, можно представить себе школьные классы. Школьники в каждом классе отсортированы от а до я: Если select-ить всех школьников из 1 "а", то они возвратятся уже отсортированными без использования filesort или temporary; неважно что использовалось, ascending или descending: вернёт Однако стоит только нам взять всех школьников из обоих классов и отсортировать их, как explain тут же выдаст зловещий Using filesort или Using temporary: Произошло это очевидно потому, что значения уже не могут быть взяты по pipeline-у, поэтому СУБД нужно сортировать их самостоятельно. Посмотрим на ещё один пример: нужно отсортировать предыдущий запрос по message. При этом атрибут уже отсортирован, но уже относительно префикса индекса, т.е. относительно datetime.  Explain: Почему произошёл filesort? Вспомним пример со школьниками: если тридцать школьников (суффикс индекса) учатся в одном классе (префикс индекса), то они отсортированы по pipeline–у; однако при выборе нескольких классов нужно сортировать вручную (брать в руки журнал и на новом листе бумаги создавать новый отсортированный список со всеми учениками 1го класса). Здесь такой же принцип, но с поправкой на то, что datetime – атрибут полностью уникальный (равносильно тому, что в каждом классе учится только один школьник). Значит, СУБД нужно проделать самостоятельную сортировку. Поэтому в данном запросе filesort – это норма, от которой никуда не денешься. Однако после анализа самых частых sql–запросов, совершаемых над таблицей log, выяснилось, что самая частая операция, совершаемая в приложении — это поиск логов с конкретным message–м и типом, без конкретных временных промежутков.
Например, поиск всех ошибок с сообщением "message 183".
Такой запрос будет уже неоптимальным и выполняться будет около 30 секунд:  Explain этого запроса выдал такую картину: Теперь видно, что индекс вовсе не используется. Оно и понятно: слишком затратно искать информацию по суффиксу индекса. Делаем вывод, что нужно менять структуру индекса так, чтобы message был на первом месте: Теперь запрос, который при прошлом индексе ронял бы БД, выглядит вполне оптимально: Однако старый запрос на получение мессаджей по конкретной дате теперь неоптимален.
Но если он выполняется редко, то можно оставить его неоптимальным, поскольку основная задача оптимизации выполнена: все частые запросы к базе данных оптимизированы. Не всегда самый селективный столбец должен стоять в префиксе составного индекса.
Бывают ситуации, когда атрибут, у которого куча повторов в таблице, является наиболее часто выбираемым. И толку его ставить вправо нет, потому что операции поиска по нему приведут к полному перебору индексного дерева.  Есть люди, которые считают мифом ставить самый селективный столбец влево.
Сложно назвать это мифом, поскольку на практике самый селективный столбец даёт больше преимущества в поиске над остальными.  Просто помимо селективности нужно обращать внимание и на саму предметную область, и отталкиваться в первую очередь от её требований, а не только от сухих данных. Погромист, строитель светлого будущего >_<