Na tej stronie znajdziesz wyjaśnienie danych wyjściowych zapytania wykonanego za pomocą funkcji Wyjaśnienie zapytania. Aby dowiedzieć się, jak wykonać zapytanie za pomocą funkcji Query Explain, przeczytaj artykuł Analizowanie wykonywania zapytań za pomocą funkcji Query Explain.
Powszechne koncepcje
W drzewie wykonania używane są te powszechne pojęcia i terminy:
Wiersze i rekordy
Terminy wiersz i rekord są używane w odniesieniu do dokumentu lub wpisu w indeksie.
Zmienne
$
oznacza zmienną, która jest tworzona lub do której odwołuje się drzewo wykonania. Na przykład: $foo_1
. Te zmienne są zwykle używane do odwoływania się do zawartości dokumentu lub wartości wyrażenia obliczonego podczas wykonywania zapytania.
W węzłach wykonania mogą się pojawiać te zmienne wewnętrzne:
$__key__
– klucz to wewnętrzny identyfikator dokumentu. Jest to bezwzględny, unikalny identyfikator zawierający projekt, bazę danych i pełną ścieżkę dokumentu.$__id__
– identyfikator jest unikalnym identyfikatorem dokumentu w kolekcji. Jest on unikalny w ramach jednej kolekcji.
Rozważmy przykład, w którym węzeł Compute
służy do obliczania __id__
z dokumentu __key__
:
Compute
| $__id__1: _id($__key__)
| records returned: 1
Ograniczenia i zakresy
Niektóre węzły skanowania używają atrybutów constraints
i ranges
do opisywania zakresu skanowanych wartości. Te atrybuty używają formatu drzewa zakresów, który zawiera listę wartości. Te wartości odpowiadają uporządkowanej liście kluczy, które występują w definicji indeksu. Na przykład pierwszy zakres, który pojawia się w drzewie, czyli (1..5]
, odpowiada ograniczeniom pierwszego klucza, czyli a
, na uporządkowanej liście kluczy:
| index: type=CollectionGroupIndex, id=CICAgOjXh#EK, keys=[a ASC, b ASC, __key__ ASC]
| constraints: /
|----(1..5]
|----[1L]
Każdy poziom wcięcia wskazuje ograniczenie stosowane do następnego klucza na liście. Nawiasy kwadratowe oznaczają przedział domknięty, a nawiasy okrągłe – przedział otwarty. W tym przypadku ograniczenie przekłada się na 1 < "a" <= 5
i "b" = 1
.
W tym przykładzie z wieloma gałęziami dla a
ograniczenie odpowiada 1 < a <= 5 OR a = 10
:
| constraints: /
|----(1L, 5L]
|----[10L]
Kluczowe zmienne
W niektórych węzłach skanowania (np. SequentialScan
) występuje zarówno lista kluczy w ramach atrybutu index
, jak i osobny atrybut keys
w węźle Scan
. Atrybut keys
w węźle Scan
oznacza nazwę zmiennej każdego klucza w definicji indeksu, w kolejności. Zmiennych można używać do odwoływania się do wartości w czasie działania skanowanego pola w dalszej części drzewa wykonania.
W tym przykładzie wartość pola user
w bieżącym dokumencie jest mapowana na zmienną $user_1
, a wartość date_placed
na $date_placed_1
.
index: type=CollectionGroupIndex, id=CICAgOjXh4EK, keys=[user ASC, date_placed ASC, __key__ ASC]
keys: [user ASC, date_placed ASC, __key__ ASC]
Węzły wykonawcze
Drzewo wykonywania zapytania może zawierać te węzły:
SeekingScan
Reprezentuje skanowanie dynamiczne, w którym zwracane wiersze mogą nie znajdować się w jednym sekwencyjnym zakresie indeksu, a do spełnienia zapytania należy wykonać wiele odrębnych skanowań.
Na przykład zapytanie, w którym występuje warunek a
i b
= 1, działające na indeksie ["a" ASC, "b" ASC]
, musiałoby skanować i zwracać oddzielny, potencjalnie nieciągły zakres dla każdej odrębnej wartości a
.
Jest to bardziej wydajne niż pełne TableScan
, ale mniej wydajne niż pojedyncze SequentialScan
w indeksie złożonym ["b" ASC, "a" ASC]
.
• SeekingScan
| constraints: /
|----(-∞..+∞)
|----[1L]
| index: type=CollectionGroupIndex, id=CAE, keys=[user ASC, quantity ASC, __key__ ASC]
| keys: [user ASC, quantity ASC, __key__ ASC]
| properties: Selection { user }
| records returned: 1
| records scanned: 1
SequentialScan
Reprezentuje skanowanie statycznego, sekwencyjnego zakresu wierszy w pamięci, które można wykonać w ramach jednej operacji odczytu.
Symbol key ordering length
oznacza liczbę kluczy, które muszą zostać zachowane i zwrócone w pierwotnej kolejności. W przypadku schematu [k1, k2, k3]
długość kolejności kluczy równa 0 oznacza, że skanowanie może zwracać wyniki w dowolnej kolejności, 1 oznacza kolejność według k1, ale wiersze o tej samej wartości k1 mogą występować w dowolnej kolejności, a 3 zwraca dokumenty w dokładnie posortowanej kolejności.
• SequentialScan
| index: type=CollectionGroupIndex, id=CAE, keys=[user ASC, date_placed ASC, __key__ ASC]
| key ordering length: 3
| keys: [user ASC, date_placed ASC, __key__ ASC]
| limit: 10
| properties: Selection { a }
| ranges: /
| records returned: 1
| records scanned: 1
UniqueScan
Reprezentuje skanowanie statycznego, sekwencyjnego zakresu wierszy w pamięci masowej z usuwaniem duplikatów wierszy w pamięci.
• UniqueScan
| index: type=CollectionGroupIndex, id=CAE, keys=[user ASC, date_placed ASC, __key__ ASC]
| keys: [user ASC, date_placed ASC, __key__ ASC]
| properties: Selection { a }
| ranges: /
|----(-∞..+∞)
| records returned: 1
| records scanned: 1
TableAccess
Łączy identyfikator dostarczonego wiersza z rzeczywistą zawartością wiersza z pamięci podstawowej. TableAccess
jest wymagane, jeśli węzeł nadrzędny (lub końcowy wynik zapytania) wymaga podzbioru pól z dokumentów.
• TableAccess
| order: PRESERVE_INPUT_ORDER
| peak memory usage: 4.00 KiB (4,096 B)
| properties: *
| records returned: 1
LookupById
Wykonuje złączenie, wyszukując dokumenty w obcej kolekcji według ich identyfikatora. Identyfikatory do wyszukania pochodzą z pola w dokumentach wejściowych. Wyniki wyszukiwania są dodawane jako nowe pole do dokumentów wejściowych.
• LookupById
| local_field: $localField_1
| foreign_datasource: (default)#/**/foreign
| output: $output_1
TableScan
Pełne, nieuporządkowane skanowanie kolekcji. Używana, gdy zapytanie jest wykonywane bez powiązanego indeksu.
Kolejność może być STABLE
lub UNDEFINED
, przy czym STABLE
oznacza kolejność deterministyczną.
• TableScan
| order: STABLE
| properties: *
| records returned: 1
| records scanned: 1
| source: (default)#/**/collection
HashAggregate
Implementacja operacji agregujących oparta na hashach. Wymaga zmaterializowania całej grupy w pamięci przed zwróceniem wyniku i nie może przekraczać limitu pamięci zapytania.
• HashAggregate
| aggregations: [sum($b_1) AS total]
| groups: [$a_1]
| peak memory usage: 4.00 KiB (4,096 B)
| records returned: 0
StreamAggregate
Specjalistyczny węzeł agregujący, który utrzymuje stan tylko dla jednej grupy naraz, co zmniejsza szczytowe wykorzystanie pamięci. Używane, gdy węzeł podrzędny zwraca grupy sekwencyjnie. Na przykład podczas grupowania według różnych wartości pola przy użyciu indeksu w tym polu.
• StreamAggregate
| keys: [foo ASC, bar ASC]
| properties: Selection { baz }
| aggregations: [$sum($foo_1) AS baz]
MajorSort
Wykonuje operację sortowania na stałym zestawie właściwości. Materializuje wszystkie rekordy w pamięci naraz i zwraca posortowane wartości w kolejności. Rozmiar zbioru sortowania jest ograniczony przez limit pamięci zapytania.
Gdy podany jest kolejny limit, do zmniejszenia wykorzystania pamięci używany jest algorytm sortowania top-k. Umożliwia sortowanie dowolnie dużego zbioru rekordów, o ile pamięć używana do przechowywania k rozważanych elementów nie przekracza limitu.
• MajorSort
| fields: [a ASC, b DESC]
| limit: 10
| peak memory usage: 4.00 KiB (4,096 B)
| records returned: 1
Concat
Łączy wyniki wielu węzłów podrzędnych i zwraca wynik do węzła nadrzędnego. Ten węzeł nie usuwa duplikatów wyników, które pojawiają się w wielu węzłach podrzędnych, a kolejność zwracanych wyników jest niedeterministyczna.
• Concat
├── • TableAccess
...
├── • TableAccess
Zasoby obliczeniowe
Oblicza zestaw wyrażeń, przypisując wyniki do zestawu zmiennych.
• Compute
| $user_1: user
| $full_name_1: str_concat($first_name_1, " ", $last_name_1)
| $address_1: UNSET
| records returned: 1
Filtr
Selektywnie zwraca wiersze tylko wtedy, gdy pasują one do podanego wyrażenia.
• Filter
| expression: $eq(foo, "bar")
| records returned: 1
Wartości
Tworzy sekwencję wartości dosłownych do przetworzenia. Używane głównie wtedy, gdy zestaw dokumentów jest podawany jako dane wejściowe zapytania.
• Values
| expression: [{__key__=/col/1}, {__key__=/col/2}]
Rozgrupuj
Usuwa zagnieżdżenie wartości wygenerowanej przez węzeł podrzędny.
• Unnest
| expression: foo AS unnested_foo
Limit
Ogranicza liczbę wierszy zwracanych do węzła nadrzędnego.
• Limit
| limit: 10
| records returned: 1
Przesunięcie
Pomija określoną liczbę wierszy wygenerowanych przez węzeł podrzędny.
• Offset
| offset: 10
| records returned: 1