Veja Como o MySQL usa índices .
Também valide se o MySQL ainda executa uma varredura de tabela completa depois de adicionar mais de 2.000 linhas ao seu
user_metrics
tabela. Em tabelas pequenas, o acesso por índice é realmente mais caro (em termos de E/S) do que uma varredura de tabela, e o otimizador do MySQL pode levar isso em consideração. Ao contrário do meu post anterior , acontece que o MySQL também está usando um otimizador baseado em custo , o que é uma notícia muito boa - isto é, desde que você execute seu
ANALYZE
pelo menos uma vez quando você acredita que o volume de dados em seu banco de dados é representativo do uso diário futuro. Ao lidar com otimizadores baseados em custo (Oracle, Postgres, etc.), você precisa certificar-se de executar periodicamente
ANALYZE
em suas várias mesas à medida que seu tamanho aumenta em mais de 10-15%. (O Postgres fará isso automaticamente para você, por padrão, enquanto outros RDBMSs deixarão essa responsabilidade para um DBA, ou seja, você.) Por meio de análise estatística, ANALYZE
ajudará o otimizador a ter uma ideia melhor de quanta E/S (e outros recursos associados, como CPU, necessários, por exemplo, para classificação) estarão envolvidos ao escolher entre vários planos de execução candidatos. Falha ao executar ANALYZE
pode resultar em decisões de planejamento muito ruins, às vezes desastrosas (por exemplo, consultas de milissegundos levando, às vezes, horas devido a loops aninhados ruins em JOIN
s.) Se o desempenho ainda for insatisfatório após executar
ANALYZE
, normalmente você poderá contornar o problema usando dicas, por exemplo, FORCE INDEX
, enquanto em outros casos você pode ter tropeçado em um bug do MySQL (por exemplo, este mais antigo , que poderia ter mordido você se você usasse o nested_set
do Rails ). Agora, já que você está em um aplicativo Rails , será complicado (e anulará o propósito de
ActiveRecord
) para emitir suas consultas personalizadas com dicas em vez de continuar usando o ActiveRecord
-gerados. Eu mencionei que em nosso aplicativo Rails todos
SELECT
as consultas caíram abaixo de 100ms após mudar para o Postgres, enquanto algumas das junções complexas geradas pelo ActiveRecord
ocasionalmente levaria até 15s ou mais com o MySQL 5.1 por causa de loops aninhados com varreduras de tabelas internas, mesmo quando os índices estavam disponíveis. Nenhum otimizador é perfeito e você deve estar ciente das opções. Outros possíveis problemas de desempenho a serem observados, além da otimização do plano de consulta, são o bloqueio. Isso está fora do escopo do seu problema.