Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

MySQL não está usando índices com cláusula WHERE IN?


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.