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