Votre problème de performances observé lors d'une requête initiale est probablement l'un des problèmes suivants (dans l'ordre approximatif de probabilité) :
1) Votre application/service Web a une surcharge à initialiser à la première requête (c'est-à-dire l'allocation de mémoire, la configuration de pools de connexion, la résolution de DNS, ...).
2) Les index ou les données que vous avez demandés ne sont pas encore en mémoire et doivent donc être chargés.
3) L'Optimiseur de requête peut prendre un peu plus de temps à s'exécuter lors de la première requête, car il compare l'exécution du plan pour votre modèle de requête.
Il serait très utile de tester la requête via le mongo
shell et isolez si la surcharge est liée à MongoDB ou à votre service Web (plutôt que de chronométrer les deux, comme vous l'avez fait).
Voici quelques notes relatives à MongoDB.
Mise en cache
MongoDB n'a pas de temps de "cache" pour les documents en mémoire. Il utilise des fichiers mappés en mémoire pour les E/S de disque et les documents en mémoire sont basés sur vos requêtes actives (documents/index que vous avez récemment chargés) ainsi que sur la mémoire disponible. Le gestionnaire de mémoire virtuelle du système d'exploitation est en charge de la la mise en cache , et suivra généralement un algorithme LRU (Least-Recently Used) pour décider quelles pages échanger hors de la mémoire.
Utilisation de la mémoire
Le comportement attendu est qu'au fil du temps, MongoDB se développera pour utiliser toute la mémoire libre pour stocker votre ensemble de données de travail actif.
En regardant votre db.stats()
fourni numéros (et en supposant que c'est votre seul base de données), il semble que la taille actuelle de votre base de données soit d'environ 1 Go, vous devriez donc pouvoir tout conserver dans votre RAM totale de 10 Go, sauf si :
- il existe d'autres processus en compétition pour la mémoire
- vous avez redémarré votre
mongod
serveur et ces documents/index n'ont pas encore été demandés
Dans MongoDB 2.2, il y a un nouveau touch
commande que vous pouvez utiliser pour charger des index ou des documents en mémoire après un redémarrage du serveur. Cela ne doit être utilisé qu'au démarrage initial pour "préchauffer" le serveur, sinon vous risquez de forcer inutilement les données "actives" réelles hors de la mémoire.
Sur un système Linux, par exemple, vous pouvez utiliser le top
commande et devrait voir que :
- les octets virtuels/VSIZE auront tendance à être la taille de la base de données entière
- si le serveur n'a pas d'autres processus en cours d'exécution, les octets résidents/RSIZE seront la mémoire totale de la machine (cela inclut le contenu du cache du système de fichiers)
mongod
ne doit pas utiliser swap (puisque les fichiers sont mappés en mémoire)
Vous pouvez utiliser le mongostat
outil pour obtenir une vue rapide de votre mongod
activité .. ou plus utilement, utilisez un service comme MMS
pour surveiller les métriques au fil du temps.
Optimiseur de requête
L'Optimiseur de requête
de MongoDB compare l'exécution du plan pour un modèle de requête toutes les ~1 000 opérations d'écriture, puis met en cache le plan de requête "gagnant" jusqu'à la prochaine exécution de l'optimiseur .. ou vous appelez explicitement un explain()
sur cette requête.
Cela devrait être simple à tester :exécutez votre requête dans le mongo
shell avec .explain()
et regardez les minutages ms, ainsi que le nombre d'entrées d'index et de documents numérisés. Le timing d'un expliquer () n'est pas le temps réel que les requêtes prendront pour s'exécuter, car il inclut le coût de la comparaison des plans. L'exécution typique sera beaucoup plus rapide .. et vous pouvez rechercher des requêtes lentes dans votre mongod
journal.
Par défaut, MongoDB enregistrera toutes les requêtes plus lentement que 100 ms, ce qui constitue un bon point de départ pour rechercher des requêtes à optimiser. Vous pouvez ajuster la valeur ms lente avec le --slowms
config option, ou en utilisant le Database Profiler
commandes.
Autres lectures dans la documentation MongoDB :
- Mise en cache
- Vérification de l'utilisation de la mémoire du serveur
- Profileur de base de données
- Expliquer
- Surveillance et diagnostic