2012-11-15 2 views
2

Je fais mon premier projet avec MongoDB et de ce que j'ai vu la création implicite de collections est la pratique recommandée (par exemple, db.myCollection.insert() créera la collection la première fois J'utilise PHP et j'utilise différentes collections de cette façon, mais le problème est que je ne sais pas où je devrais créer les index dont j'ai besoin pour cette collection. Comme je ne saurais pas quand une collection est créée, l'approche naïve appelait ensureIndex() juste avant chaque opération sur cette collection (ce qui ne sonne pas très bien). Ou chaque fois qu'une connexion à la base de données est faite, assurez-vous que les index existent (que se passe-t-il si je crée un index sur une collection qui n'a pas été créée?)MongoDB initial déploiement et index

Des conseils de bonnes pratiques pour cela?

Répondre

2

Je ne sais pas si elle est la meilleure pratique, mais je tends de ne pas mettre le EnsureIndex dans l'application. Je mets généralement ceux dont je suis sûr que je vais avoir besoin d'utiliser le shell db. Ensuite, je garde un œil pendant le test de charge (ou quand les choses commencent à ralentir dans la production) et ajoute tout ce que j'ai raté à nouveau dans le shell. Vous pouvez construire des index en arrière-plan en faisant ensureIndex ({a: 1}, {background: true}), donc les construire plus tard n'est pas aussi terrible que d'autres dbs.

MongoDB a un bon profileur pour trouver ce qui se passe lentement: http://www.mongodb.org/display/DOCS/Database+Profiler. 10gen (la contrepartie commerciale de MongoDB) a un service de surveillance gratuit dont on parle beaucoup bien que je ne l'ai pas encore utilisé: http://www.10gen.com/mongodb-monitoring-service. Mais pour autant que se passe-t-il lorsque vous appelez db.collection.ensureIndex() avant que la collection soit créée, elle crée la collection et y place l'index.

Si vous le voulez vraiment dans l'application, j'irais avec la deuxième option que vous mettez en avant (assurez-vous d'indexer juste après db connect) au lieu d'avant chaque opération. Je sauverais probablement quelque chose dans la base de données quand je l'ai fait, ils ne courent pas à chaque fois s'il y a plus d'un couple. Je ne sais pas php mais voici le code pseudo:

var test = db.systemChecks.findOne({indexes : true}) 
if (test == null) //item doesn't exist 
{ 
    //do all the ensureIndex() commands 
    db.systemChecks.insert({indexes : true}) 
} 

n'oubliez pas de supprimer l'élément SystemCheck si vous vous trouvez besoin de plus d'indices plus tard pour exécuter les index

1

En fait, ensureIndex() est exactement ce que vous devrez faire. Je le ferais dans le constructeur de chaque modèle qui utilise une connexion spécifique - si vous avez un de ces modèles). ensureIndex() s'assurera qu'un index n'est créé que s'il n'existe pas déjà. Vous pouvez également le faire lorsque vous créez votre connexion à la base de données. Si vous exécutez ensureIndex() sur une collection non existante, il suffit de créer cette collection et de créer des index vides (car il n'y a pas encore de documents).

À l'avenir, le pilote PHP également en cache si ensureIndex() a déjà été exécuté dans la même demande, ce qui en fait un no-op: https://jira.mongodb.org/browse/PHP-581