Szukam optymalizacji wydajności zapytania. Moim celem jest znalezienie wszystkich dokumentów mieszczących się w podanym zakresie dat. Zbiór jest dość duży, liczy ponad 6 milionów dokumentów. Więc zapytanie wygląda następująco:

db.collection.find({
    createdAt: {
        $gte: new Date('2018-06-19'), 
        $lt: new Date('2018-06-22')
    }
})

Działa przez ponad 10 minut. Czy jest sposób, aby wykorzystać fakt, że daty są posortowane? Chodzi mi o to, że dokumenty są wstawiane w czasie tworzenia, więc każdy dokument poza ostatnim dokumentem mieszczącym się w zakresie będzie poza zakresem, ale mongo prawdopodobnie o tym nie wie i szuka tych dokumentów, w których daty są już poza zakresem?

0
filemonczyk 8 marzec 2020, 21:45

2 odpowiedzi

Najlepsza odpowiedź

Aplikacje i użytkownicy, których szukają, to kwerenda o wydajności w ciągu kilku setek milisekund (a nie 10 minut) dla kolekcji zawierającej kilka milionów dokumentów. Indeksy służą do szybkiego uruchamiania tych zapytań.

Zapytanie zakresowe, takie jak powyżej, można przyspieszyć, tworząc indeks pojedynczego pola w polu daty filtru wyszukiwania zapytania. Indeksy przechowują wartość pola klucza indeksu i adres dokumentu w kolekcji - jest to niewielka ilość danych. W przypadku typowej kolekcji, zapytania i indeksu dane kolekcji i indeks muszą być dostępne (lub zmieścić się) w pamięci (nazywanej zestawem roboczym), aby były efektywnie wykorzystywane. Po uruchomieniu zapytania indeks jest uzyskiwany na podstawie kryteriów filtru, a następnie odpowiednich dokumentów.

Nie ma sposobu, aby kwerenda działała szybciej bez użycia indeksu z milionami dokumentów (pamiętaj, że może to nie mieć znaczenia w przypadku kilku tysięcy dokumentów). Można to zademonstrować praktycznie w środowisku deweloperskim z przykładowym zestawem kilku milionów dokumentów, indeksem w polu filtru zapytania i uruchomieniem testowym.

Narzędziem, które ma być użyte do wykonania tego testu, jest generowanie planu zapytań przy użyciu funkcji wyjaśnienia. metoda wyjaśniania ma tryb „executationStats”, który podaje szczegóły, takie jak użyty indeks (jeśli istnieje), czas uruchomienia zapytania, klucze indeksowe, do których uzyskano dostęp, liczbę zwróconych dokumentów, różne etapy wykonywania zapytania itp. Etapy planu pokażą, czy indeks jest używany przez zapytanie. Zazwyczaj zapytanie uruchomione przy użyciu indeksu spowoduje wyświetlenie skanowania indeksowanego (IXSCAN), a jeśli nie zostanie użyty żaden indeks, będzie to skanowanie kolekcji (COLLSCAN).

Utworzony indeks może być również używany z innymi zapytaniami, jeśli ma to zastosowanie, a także z operacjami sortowania. Ponadto indeks może być indeksem złożonym (używającym wielu pól) i jeśli można go używać z innymi zapytaniami.

Zobacz też FAQ: indeksy, aby uzyskać więcej informacji. Ponieważ masz już dużą kolekcję, zapoznaj się z Tworzeniami indeksu dla zaludnionych zbiorów. Jeżeli chodzi o.

db.collection.stats () polecenie jest przydatne do znalezienia rozmiaru kolekcji i indeksu.

Oprócz indeksowania, rzutowanie tylko wymaganych pól może również wpływać na wydajność zapytania.

0
prasad_ 9 marzec 2020, 02:31

MongoDB nie może wykorzystać „faktu”, ponieważ nie wie, jakie dokumenty binarne są przechowywane.

Jeśli wyszukujesz według nieindeksowanego pola, Mongodb wykonuje COLLSCAN (wyjaśnione tutaj)

Indeksowanie:

Od wersji 4.2, MongoDB używa zoptymalizowanego procesu kompilacji, który blokuje wyłączność tylko na początku i na końcu procesu kompilacji.

Przed wersją 4.2 musisz określić opcję background

db.collection.createIndex({createdAt:1}, {background:true})

https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/#options-for-all-index-types

0
Valijon 8 marzec 2020, 20:28