Seu problema de desempenho observado em uma consulta inicial provavelmente é um dos seguintes problemas (em ordem aproximada de probabilidade):
1) Seu aplicativo / serviço da Web tem alguma sobrecarga para inicializar na primeira solicitação (ou seja, alocar memória, configurar pools de conexão, resolver DNS, ...).
2) Índices ou dados que você solicitou ainda não estão na memória, então precisam ser carregados.
3) O Otimizador de consultas pode demorar um pouco mais para ser executado na primeira solicitação, pois está comparando a execução do plano para seu padrão de consulta.
Seria muito útil testar a consulta através do
mongod
shell e isole se a sobrecarga está relacionada ao MongoDB ou ao seu serviço da Web (em vez de cronometrar ambos, como você fez). A seguir estão algumas notas relacionadas ao MongoDB.
Cache
O MongoDB não tem um tempo de "cache" para documentos na memória. Ele usa arquivos mapeados em memória para E/S de disco e os documentos na memória são baseados em suas consultas ativas (documentos/índices que você carregou recentemente), bem como na memória disponível. O gerenciador de memória virtual do sistema operacional é responsável pelo caching , e normalmente seguirá um algoritmo Least-Recently Used (LRU) para decidir quais páginas trocar de memória.
Uso de memória
O comportamento esperado é que, com o tempo, o MongoDB cresça para usar toda a memória livre para armazenar seu conjunto de dados de trabalho ativo.
Olhando para o
db.stats()
fornecido números (e supondo que seja seu único database), parece que o tamanho do seu banco de dados é de cerca de 1 Gb, então você deve ser capaz de manter tudo dentro de sua RAM total de 10 Gb, a menos que:- há outros processos competindo pela memória
- você reiniciou seu
mongod
servidor e esses documentos/índices ainda não foram solicitados
No MongoDB 2.2, há um novo
touch
comando que você pode usar para carregar índices ou documentos na memória após a reinicialização do servidor. Isso deve ser usado apenas na inicialização inicial para "aquecer" o servidor, caso contrário, você poderá forçar inutilmente os dados "ativos" reais da memória. Em um sistema linux, por exemplo, você pode usar o
top
comando e deve ver que:- bytes virtuais/VSIZE tenderá a ser o tamanho de todo o banco de dados
- se o servidor não tiver outros processos em execução, bytes residentes/RSIZE será a memória total da máquina (isso inclui o conteúdo do cache do sistema de arquivos)
mongod
não deve usar swap (já que os arquivos são mapeados na memória)
Você pode usar o
mongostat
ferramenta para obter uma visão rápida do seu mongod
atividade .. ou mais útil, use um serviço como MMS
para monitorar as métricas ao longo do tempo. Otimizador de consultas
O MongoDB Otimizador de Consulta compara a execução do plano para um padrão de consulta a cada ~1.000 operações de gravação e, em seguida, armazena em cache o plano de consulta "vencedor" até a próxima vez que o otimizador for executado .. ou você chama explicitamente um
explain()
nessa consulta. Este deve ser simples de testar:execute sua consulta no
mongod
shell com .explain()
e observe os tempos de ms, e também o número de entradas de índice e documentos digitalizados. O tempo para uma explicação () não é o tempo real que as consultas levarão para serem executadas, pois inclui o custo de comparação dos planos. A execução típica será muito mais rápida .. e você pode procurar consultas lentas em seu mongod
registro. Por padrão, o MongoDB registrará todas as consultas mais lentas que 100 ms, portanto, isso fornece um bom ponto de partida para procurar consultas a serem otimizadas. Você pode ajustar o valor de ms lento com o
--slowms
config ou usando o Database Profiler
comandos. Leitura adicional na documentação do MongoDB:
- Cache
- Verificando o uso da memória do servidor
- Perfil de banco de dados
- Explicar
- Monitoramento e diagnóstico