Zastanawiam się, czy zapis $project tuż po instrukcji $match faktycznie zmniejsza ilość danych, które mają być przechowywane w pamięci. Jako przykład, jeśli chcemy elementu tablicy ze stronicowaniem z dokumentu użytkownika, takiego jak:

const skip = 20;
const limit = 50;

UserModel.aggregate([
            { $match: { _id: userId } },
            { $project: { _id: 0, postList: 1 } },
            { $slice: ["$postList", skip, limit] },
            { $lookup: ...
]);

Załóżmy, że w dokumencie użytkownika znajdują się inne listy i mają one bardzo duży rozmiar.

Czy więc $project pomoże poprawić wydajność, nie biorąc w pamięci innych dużych list?

1
Andro Developer 11 styczeń 2020, 16:07

1 odpowiedź

Najlepsza odpowiedź

Każdy etap agregacji skanuje dokumenty wejściowe z kolekcji (jeśli jest to pierwszy etap) lub poprzedniego etapu. Na przykład,

  • Dopasuj (filtruje dokumenty) - zmniejszy to liczbę dokumentów, ogólny rozmiar
  • Projekt (przekształca lub kształtuje dokument) - może to zmniejszyć (lub zwiększyć) rozmiar dokumentu; Liczba dokumentów pozostaje taki sam
  • Grupa - Zmniejsza liczbę dokumentów i zmienia rozmiar
  • Pomiń, Limt - Zmniejsz liczbę dokumentów
  • Sortuj - brak zmiany rozmiaru lub liczby dokumentów itp.

Każdy etap może wpływać na pamięć lub procesor lub oba. Ogólnie rzecz biorąc, rozmiar dokumentu, liczba dokumentów, indeksów i pamięć mogą wpływać na wydajność zapytania.

Ograniczenia pamięci dla agregacji są już wyraźnie określone w dokumentacji (patrz Granice rurociągu agregacji). Jeśli limit pamięci przekracza ograniczenia, agregacja zakończy się. W takich przypadkach można określić opcję agregacji { allowDiskuse: true }, a użycie tej opcji wpłynie na wydajność zapytania. Jeśli twoja agregacja działa bez żadnych problemów związanych z (jak wypowiedzenie zapytania z powodu przekroczenia limitów pamięci), wówczas nie ma problemu z wydajnością zapytania bezpośrednio.

Etapy $match i $sort Używaj indeksów, jeśli są używane na początku rurociągu. Może to poprawić wydajność.

Dodanie sceny do rurociągu oznacza dodatkowe przetwarzanie i może wpływać na ogólną wydajność. Dzieje się tak dlatego, że dokumenty z poprzedniego etapu muszą przejść do tego dodatkowego etapu. W rurociągu agregacji dokumenty są przekazywane przez każdy etap - jak w rurze, a etap wykonuje niektóre transfrmacje danych. Jeśli możesz uniknąć sceny, czasami może przynosić ogólną wydajność zapytania. Gdy liczby są duże, posiadające dodatkowe (niepotrzebne) etap jest zdecydowanie wadą. Musisz wziąć pod uwagę zarówno ograniczenia pamięci, jak i rozmiar i liczbę dokumentów.

A $project może być użyty do zmniejszenia rozmiaru dokumentu. Ale czy trzeba dodać ten etap? To zależy od czynników, o których wspomniałem powyżej i implementację i wniosek. Dokumentacja (Optymalizacja projekcji) mówi:

Rurociąg agregacji może określić, czy wymaga tylko podzbioru pól w dokumentach w celu uzyskania wyników. Jeśli tak, rurociąg wykorzystuje tylko te wymagane pola, zmniejszając ilość danych przechodzących przez rurociąg.

1
prasad_ 13 styczeń 2020, 04:03