Le système que je développe actuellement sur, utilise MongoDB 2.4.4MongoDB trouver lent avec regex
J'ai une collection d'utilisateurs.
Il y a un indice combiné: { "LASTNAME" : 1 , "FIRSTNAME" : 1 , "EMAIL" : 1 , "CITY" : 1 , "STATUS" : 1}
J'ai aussi essayé avec des indices simples, sans augmentation de la performance
Le système contient les enregistrements de test 400.000.
La requête (Java debug de org.springframework.data.mongodb.core.query.Query):
{ "LASTNAME" : { "$regex" : "^Schm"}},
Fields: { "FIRSTNAME" : 1 , "EMAIL" : 1 , "CITY" : 1 , "STATUS" : 1 ,"LASTNAME" : 1},
Sort: { "LASTNAME" : 1 , "FIRSTNAME" : 1 , "EMAIL" : 1 , "CITY" : 1 , "STATUS" : 1}
dans 16ms.That est effectue fantastique.
Cette requête n'apparaît pas dans la console MongoDB (aucune information de débogage à afficher ici).
Mais, j'aime chercher ne commence pas seulement, il devrait également être insensible à la casse.
la requête:
{ "LASTNAME" : { "$regex" : "^Schm" , "$options" : "i"}},
Fields: { "FIRSTNAME" : 1 , "EMAIL" : 1 , "CITY" : 1 , "STATUS" : 1 , "LASTNAME" : 1},
Sort: { "LASTNAME" : 1 , "FIRSTNAME" : 1 , "EMAIL" : 1 , "CITY" : 1 , "STATUS" : 1}
effectue au sein de 897ms. C'est inacceptable lent.
Console Mongo montre ceci:
query: { query: { LASTNAME: /^Schm/i },
orderby: { LASTNAME: 1, FIRSTNAME: 1, EMAIL: 1, CITY:1, STATUS: 1 }
} cursorid:1252405545564528 ntoreturn:25 ntoskip:0 nscanned:297651
keyUpdates:0 numYields: 1 locks(micros) r:1391715 nreturned:25 reslen:4422 897ms
Comme on peut le voir. Ce n'est pas le problème scanAndOrder qui pointe sur les problèmes d'index.
Ensuite, j'ai essayé de le résoudre la prochaine façon ce qui correspond le plus à des scénarios (inséré de l'utilisateur, minuscules et majuscules), mais c'est aussi plus lent. Mon attente était, qu'il effectue trois fois aussi longtemps que la première requête.
la requête:
{ "$or" : [ { "LASTNAME" : { "$regex" : "^Schm"}} , { "LASTNAME" : { "$regex" : "^schm"}} , { "LASTNAME" : { "$regex" : "^SCHM"}}]},
Fields: { "FIRSTNAME" : 1 , "EMAIL" : 1 , "CITY" : 1 , "STATUS" : 1 , "LASTNAME" : 1},
Sort: { "LASTNAME" : 1 , "FIRSTNAME" : 1 , "EMAIL" : 1 , "CITY" : 1 , "STATUS" : 1}
effectue au sein de 1300ms. Rien d'autre à dire.
console MongoDB:
query: { query: { $or: [ { LASTNAME: /^Schm/ }, { LASTNAME: /^schm/ }, { LASTNAME: /^SCHM/ } ] },
orderby: { LASTNAME: 1, FIRSTNAME: 1, EMAIL: 1, CITY: 1, STATUS: 1 }
} cursorid:43560166842085 ntoreturn:25 ntoskip:0 nscanned:297651
keyUpdates:0 numYields: 1 locks(micros) r:1531168 nreturned:25 reslen:4422 1300ms
Alors, comment puis-je recherche insensible à la casse qui a presque la vitesse de la première recherche? Maximal 150ms!
En note, j'ai enlevé les balises Java puisque cette question est seulement liée à Mongo, pas Java –
Pouvez-vous s'il vous plaît poster le 'explain()' pour votre requête '$ or' –
Je ne sais pas comment , en utilisant Spring MongoTemplate. Actuellement, je pense à passer à mongo-java-driver ... – Nabor