См. Как MySQL использует индексы .
Также проверьте, выполняет ли MySQL полное сканирование таблицы после добавления дополнительных примерно 2000 строк в вашу таблицу user_metrics
. В небольших таблицах доступ по индексу на самом деле дороже (с точки зрения ввода / вывода), чем сканирование таблицы, и оптимизатор MySQL может принять это во внимание.
В отличие от моего предыдущего поста , получается, что MySQL также использует оптимизатор на основе затрат , что является очень хорошей новостью, то есть, если вы запустите свой ANALYZE
хотя бы один раз, когда вы считаете, что объем данных в вашей базе данных составляет представитель будущего ежедневного использования.
При работе с оптимизаторами на основе затрат (Oracle, Postgres и т. Д.) Необходимо периодически запускать ANALYZE
для ваших различных таблиц, поскольку их размер увеличивается более чем на 10-15 %. (По умолчанию Postgres сделает это для вас автоматически, тогда как другие РСУБД возложат эту ответственность на администратора баз данных, то есть на вас.) Благодаря статистическому анализу ANALYZE
поможет оптимизатору лучше понять, сколько операций ввода-вывода (и другие связанные ресурсы, такие как ЦП, необходимые, например, для сортировки), будут задействованы при выборе между различными вариантами выполнения планов. Невыполнение ANALYZE
может привести к очень плохим, иногда катастрофическим планировочным решениям (например, миллисекундные запросы занимают, иногда, часы из-за неправильных вложенных циклов на JOIN
с.)
Если производительность по-прежнему неудовлетворительна после запуска ANALYZE
, вы, как правило, сможете обойти проблему, используя подсказки, например, FORCE INDEX
, тогда как в других случаях вы могли бы наткнуться на ошибку MySQL (например, эту более старую , которая могла бы вас укусить, если бы вы использовали Rails 'nested_set
).
Теперь, , так как вы находитесь в приложении Rails , будет неудобно (и победит цель ActiveRecord
) выдавать ваши пользовательские запросы с подсказками вместо того, чтобы продолжать использовать ActiveRecord
- сгенерированные.
Я уже упоминал, что в нашем приложении Rails все SELECT
запросов упали ниже 100 мс после переключения на Postgres, тогда как некоторые из сложных объединений, генерируемых ActiveRecord
, иногда занимали бы 15 с или более с MySQL 5.1 из-за вложенных циклов со сканированием внутренней таблицы, даже когда индексы были доступны. Ни один оптимизатор не идеален, и вы должны знать о возможных вариантах. Другие потенциальные проблемы с производительностью, о которых следует знать, кроме оптимизации плана запросов, блокируются. Хотя это выходит за рамки вашей проблемы.