Перезапись жирным шрифтом
Этот код функционально не идентичен, но ...
Поскольку вы хотите знать о distinct
ftopic.id и fpost.idЯ собираюсь быть смелым и предложить два ВНУТРЕННИХ СОЕДИНЕНИЯ вместо ВЛЕВОГО СОЕДИНЕНИЯ.Тогда, поскольку два идентификатора являются автоинкрементными, они больше не будут повторяться, поэтому вы можете сбросить distinct
.
SELECT
fcat.id
, fcat.title
, fcat.description
, count(ftopic.id) as number_topics
, count(fpost.id) as number_posts
FROM fcat
INNER JOIN ftopic ON fcat.id = ftopic.cat_id
INNER JOIN fpost ON ftopic.id = fpost.topic_id
GROUP BY fcat.id
ORDER BY fcat.ord
LIMIT 100;
Это зависит от ваших данных, если это то, что вы ищете, но я предполагаю, что это будет быстрее.
Хотя все ваши индексы в порядке.
MySQL не использует индексы для небольших размеров выборки!
Обратите внимание, что список explain
, который MySQL имеет только 11 строк , следует учитывать для fcat.Этого недостаточно для того, чтобы MySQL действительно начал беспокоиться об индексах, поэтому этого не происходит.
Поскольку переход к индексу для небольшого числа строк замедляет процесс.
MySQL пытается ускорить процесс, поэтому он решает не использовать индекс, это сбивает с толку многих людей, потому что мы так усердно изучаем этот индекс.Малые размеры выборки не дают хорошего объяснения!
Увеличьте размер тестовых данных, чтобы MySQL имел больше строк для рассмотрения, и вы должны начать видеть используемый индекс.
Распространенные заблуждения относительно force index
Force index
не делает не , заставляет MySQL использовать индекс как таковой.
Он намекает MySQL на использование отличного индекса от индекса, который он, естественно, мог бы использовать и это подталкивает MySQL к использованию индекса, устанавливая очень высокую стоимость сканирования таблицы.
(В вашем случае MySQL не при использовании сканирования таблицы, поэтому force index
имеетбез эффекта)
MySQL (как и большинство других СУБД на планете) очень сильно хочет использовать индексы, поэтому, если он этого не делает, то потому, что вообще не использовать индекс, быстрее,
Как MySQL узнает, какой индекс использовать
Одним из параметров, используемых оптимизатором запросов, является сохраненная мощность индексов.
Со временем эти значения меняются ...Но изучение таблицы требует времени, поэтому MySQL не сделает этого, пока вы не скажете это.
Другим параметром, влияющим на выбор индекса, является прогнозируемое время поиска диска, с которым MySQL ожидает встретиться при выполнении запроса.
Советы по улучшению использования индекса
ANALYZE TABLE
даст MySQL указание переоценить индексы и обновить распределение ключей (количество элементов). (рассмотрите возможность ежедневного / еженедельного запуска в задании cron) SHOW INDEX FROM table
отобразит распределение ключей. - Фрагменты таблиц и индексов MyISAM с течением времени.Используйте
OPTIMIZE TABLE
, чтобы фрагментировать таблицы и воссоздать индексы. FORCE/USE/IGNORE INDEX
ограничивает параметры Оптимизатор запросов MySQL должен выполнять ваш запрос.Учитывайте только сложные запросы. - Время эффекта вашего вмешательства с индексами на регулярной основе .Принудительный индекс, который ускоряет ваш запрос сегодня, может замедлить его завтра, потому что базовые данные изменились.