2012-10-23 14 views
7

Utknąłem z tym prostym zapytaniem prefiksu. Chociaż Mongo docs stwierdzają, że można uzyskać bardzo dobre wyniki przy użyciu formatu Prefiks regex (/^a /), zapytanie jest dość powolne, gdy próbuję posortować wyniki:Proste zapytanie przedrostkowe Mongodb z regex i sortowanie jest powolne

940 millis

db.posts.find ({hashtags:/^ noticias /}). graniczna (15) .sort ({stopień -1}).. wskazówkę ('hashtags_1_rank_-1') wyjaśnić()

{ 
"cursor" : "BtreeCursor hashtags_1_rank_-1 multi", 
"isMultiKey" : true, 
"n" : 15, 
"nscannedObjects" : 142691, 
"nscanned" : 142692, 
"nscannedObjectsAllPlans" : 142691, 
"nscannedAllPlans" : 142692, 
"scanAndOrder" : true, 
"indexOnly" : false, 
"nYields" : 1, 
"nChunkSkips" : 0, 
"millis" : 934, 
"indexBounds" : { 
    "hashtags" : [ 
     [ 
      "noticias", 
      "noticiat" 
     ], 
     [ 
      /^noticias/, 
      /^noticias/ 
     ] 
    ], 
    "rank" : [ 
     [ 
      { 
       "$maxElement" : 1 
      }, 
      { 
       "$minElement" : 1 
      } 
     ] 
    ] 
}, 
"server" : "XRTZ048.local:27017" 
} 

Jednak niesortowana wersja tego samego zapytania jest superszybka:

0 Millis

db.posts.find.. ({Hashtagów:/^ noticias /}) Ograniczenie (15) .hint ('hashtags_1_rank_-1') wyjaśnić()

{ 
"cursor" : "BtreeCursor hashtags_1_rank_-1 multi", 
"isMultiKey" : true, 
"n" : 15, 
"nscannedObjects" : 15, 
"nscanned" : 15, 
"nscannedObjectsAllPlans" : 15, 
"nscannedAllPlans" : 15, 
"scanAndOrder" : false, 
"indexOnly" : false, 
"nYields" : 0, 
"nChunkSkips" : 0, 
"millis" : 0, 
"indexBounds" : { 
    "hashtags" : [ 
     [ 
      "noticias", 
      "noticiat" 
     ], 
     [ 
      /^noticias/, 
      /^noticias/ 
     ] 
    ], 
    "rank" : [ 
     [ 
      { 
       "$maxElement" : 1 
      }, 
      { 
       "$minElement" : 1 
      } 
     ] 
    ] 
}, 
"server" : "XRTZ048.local:27017" 

}

zapytanie jest również szybki jeśli usunąć regex i sortowania:

0 Millis

db.posts.find ({hashtags: "Notícias}) Ograniczenie (15) .sort ({stopień -1}).. Wskazówkę ('hashtags_1_rank_-1'). wyjaśnić()

{ 
"cursor" : "BtreeCursor hashtags_1_rank_-1", 
"isMultiKey" : true, 
"n" : 15, 
"nscannedObjects" : 15, 
"nscanned" : 15, 
"nscannedObjectsAllPlans" : 15, 
"nscannedAllPlans" : 15, 
"scanAndOrder" : false, 
"indexOnly" : false, 
"nYields" : 0, 
"nChunkSkips" : 0, 
"millis" : 0, 
"indexBounds" : { 
    "hashtags" : [ 
     [ 
      "noticias", 
      "noticias" 
     ] 
    ], 
    "rank" : [ 
     [ 
      { 
       "$maxElement" : 1 
      }, 
      { 
       "$minElement" : 1 
      } 
     ] 
    ] 
}, 
"server" : "XRTZ048.local:27017" 

}

wydaje się, stosując zarówno regex i porządek sprawia Mongo skanować wiele rekordów. Sortowanie polega jednak na skanowaniu tylko 15, jeśli nie używam wyrażenia regularnego. Co jest nie tak?

+1

jaime, uważam, że "scanAndOrder" jest odpowiedzialny za powolność. Możesz spojrzeć na [odpowiedź Andre] (http://stackoverflow.com/questions/11871187/removing-scanandorder-true-in-my-mongodb-query-result), które mogą być podobne, jeśli nie są dokładnie takie same jak twoje kwestia. – slee

Odpowiedz

6

W wyjściu wyjaśniania scanAndOrder: true wskazuje, że zapytanie wymaga pobrania dokumentów, a następnie posortowania ich w pamięci przed zwróceniem danych wyjściowych. Jest to kosztowna operacja i będzie miała wpływ na wydajność Twojego zapytania.

Istnienie scanAndOrder: true, a także różnica nscanned i n w wyniku wyjaśniania wskazuje, że zapytanie nie korzysta z optymalnego indeksu. W tym przypadku wydaje się, że trzeba wykonać skanowanie kolekcji. Być może uda Ci się złagodzić ten problem, włączając klucze indeksów w kryteriach sort. Z moich badań:

db.posts.find({hashtags: /^noticias/ }).limit(15).sort({hashtags:1, rank : -1}).explain() 

Nie wymaga skanowania i porządek, i zwraca n i nscanned liczby rekordów szukasz. Oznaczałoby to również sortowanie na kluczu hashtags, co może być przydatne lub nie, ale powinno zwiększyć wydajność zapytania.

+0

Dzięki, to naprawdę wystarczyło.Warto również zauważyć, że limity indeksu są wywiedzione z pierwszego wyrażenia regularnego, w przypadku gdy dodajesz wiele. Na przykład to zapytanie: 'db.posts.find ({" $ and ": [{hashtags:/^ manana /}, {hashtags: /^noticias/}]}).sort({'hashtags ': 1, "ranga": - 1}). Limit (10) .explain() ' będzie miał ograniczenia indeksu na manany, a to może mieć wpływ na wydajność. W moim przypadku sortowanie zapytań z wyrażeniami regularnymi ułoŜył alfabetycznie lepszą wydajność – Darius