D'après la MongoDB
documentation, il est mentionné que:
Lorsque vous n'avez besoin que d'un sous-ensemble de champs de documents, vous pouvez obtenir de meilleures performances en renvoyant uniquement les champs dont vous avez besoin
Comment les champs de filtrage affectent les performances? Les performances sont-elles liées à la taille des données transmises sur le réseau? ou la taille des données qui seront conservées en mémoire? Comment exactement cette performance est-elle améliorée? Quelle est cette performance mentionnée dans la documentation?
J'ai des requêtes MongoDB lentes. Le renvoi d'un sous-ensemble affecte-t-il ma requête lente (j'ai un index composé sur le terrain)?
Debian 8
,MongoDB 3.6.2
Réponses:
Par défaut, les requêtes renvoient tous les champs des documents correspondants. Si vous avez besoin de tous les champs, le retour de documents complets sera plus efficace que le fait que le serveur manipule l'ensemble de résultats avec des critères de projection.
Cependant, l'utilisation de la projection pour limiter les champs à renvoyer des résultats de requête peut améliorer les performances en:
Lors de l'utilisation de la projection pour supprimer les champs inutilisés, le serveur MongoDB devra récupérer chaque document complet en mémoire (s'il n'est pas déjà là) et filtrer les résultats pour revenir. Cette utilisation de la projection ne réduit pas l'utilisation de la mémoire ou l'ensemble de travail sur le serveur MongoDB, mais peut économiser une bande passante réseau importante pour les résultats de la requête en fonction de votre modèle de données et des champs projetés.
Une requête couverte est un cas spécial où tous les champs demandés dans un résultat de requête sont inclus dans l'index utilisé, de sorte que le serveur n'a pas à extraire le document complet. Les requêtes couvertes peuvent améliorer les performances (en évitant d'aller chercher des documents) et l'utilisation de la mémoire (si d'autres requêtes ne nécessitent pas d'aller chercher le même document).
Exemples
À des fins de démonstration via le
mongo
shell, imaginez que vous avez un document qui ressemble à ceci:Le champ
b
peut représenter une sélection de valeurs (ou dans ce cas une chaîne très longue).Ensuite, créez un index sur
{a:1}
lequel se trouve un champ couramment utilisé interrogé par votre cas d'utilisation:Un simple
findOne()
sans critère de projection renvoie un résultat de requête d'environ 10 Mo:L'ajout de la projection
{a:1}
limitera la sortie au champa
et au document_id
(qui est inclus par défaut). Le serveur MongoDB manipule toujours un document de 10 Mo pour sélectionner deux champs, mais le résultat de la requête n'est plus que de 33 octets:Cette requête n'est pas couverte car le document complet doit être récupéré pour découvrir la
_id
valeur. Le_id
champ est inclus par défaut dans les résultats de la requête car il s'agit de l'identifiant unique d'un document, mais_id
il ne sera pas inclus dans un index secondaire sauf s'il est explicitement ajouté.Les mesures
totalDocsExamined
ettotalKeysExamined
dans lesexplain()
résultats montreront combien de documents et de clés d'index ont été examinés:Cette requête peut être améliorée en utilisant la projection pour exclure le
_id
champ et obtenir une requête couverte en utilisant uniquement l'{a:1}
index. La requête couverte n'a plus besoin de récupérer un document de ~ 10 Mo en mémoire, elle sera donc efficace à la fois dans l'utilisation du réseau et de la mémoire:Ce n'est pas possible sans le contexte d'une requête spécifique, un exemple de document et la sortie d'explication complète. Cependant, vous pouvez exécuter des tests de performance dans votre propre environnement pour la même requête avec et sans projection pour comparer le résultat. Si votre projection ajoute une surcharge importante au temps d'exécution global des requêtes (traitement et transfert des résultats), cela peut être un indice fort que votre modèle de données pourrait être amélioré.
S'il n'est pas clair pourquoi une requête est lente, il serait préférable de poster une nouvelle question avec des détails spécifiques à étudier.
la source
Avec une projection, vous pouvez obtenir une situation où l'ensemble de résultats provient directement de l'index.
Si vous avez un index composé
{x:1, y:1, z:1}
où aucun de x, y, z n'est _id, vous devez projeter{_id:0, x:1, y:1, z:1}
car il_id
est toujours renvoyé dans le jeu de résultats (lorsqu'il n'est pas projeté) et le moteur doit lire les fichiers de données pour l'obtenir. En effet, l'index n'a pas la valeur de _id, uniquement le pointeur sur le document où la valeur est stockée.la source
_id
de la réponse retournée, cela tient-il dans la RAM? Est ce que ça aide?_id:0
le résultat est entièrement renvoyé de la RAM, sans lire les données du disque.