W tej sekcji opisano indeksowanie w Firestore Enterprise. Wersja Firestore Enterprise nie tworzy domyślnie żadnych indeksów. Aby obniżyć koszty i zwiększyć wydajność bazy danych, utwórz indeksy dla najczęściej używanych zapytań.
Indeksy mają duży wpływ na wydajność bazy danych. Jeśli dla zapytania istnieje indeks, baza danych może skutecznie zwracać wyniki, zmniejszając ilość danych, które trzeba przeskanować, i ograniczając pracę potrzebną do posortowania wyników. Wpisy indeksu zwiększają jednak koszty miejsca na dane i ilość pracy wykonywanej podczas operacji zapisu w indeksowanych polach.
Definicja i struktura indeksu
Indeks składa się z tych elementów:
- identyfikator kolekcji,
- lista pól w danej kolekcji,
- tryb indeksu (rosnąco, malejąco lub array-contains) dla każdego pola;
Indeks może też włączyć opcje sparse lub unique.
Porządkowanie indeksów
Kolejność i kierunek sortowania każdego pola jednoznacznie definiują indeks. Na przykład te indeksy są 2 różnymi indeksami i nie można ich używać zamiennie:
| Kolekcja | Pola |
|---|---|
| miejscowości | kraj (rosnąco), populacja (malejąco) |
| miejscowości | populacja (malejąco), kraj (rosnąco), |
Podczas tworzenia indeksu do obsługi zapytania uwzględnij pola w tej samej kolejności co w zapytaniu.
Gęstość indeksu
Domyślnie wpisy indeksu przechowują dane ze wszystkich dokumentów w kolekcji. Jest to tzw. indeks nierozproszony. Wpis indeksu zostanie dodany do dokumentu niezależnie od tego, czy dokument zawiera którekolwiek z pól określonych w indeksie. Podczas generowania wpisów indeksu nieistniejące pola są traktowane jako mające wartość NULL. Aby zmienić to działanie, możesz zdefiniować indeks jako rozproszony.
Indeksy rozproszone
Indeks rozproszony indeksuje tylko te dokumenty w kolekcji, które zawierają wartość (w tym null) w co najmniej 1 z indeksowanych pól. Indeks rozproszony obniża koszty miejsca na dane i może zwiększyć wydajność.
Indeksy array-contains
Aby zoptymalizować wydajność zapytań podczas wysyłania zapytania do pola tablicy za pomocą array-contains lub array-contains-any, możesz zindeksować pole w trybie array-contains. Indeks może mieć maksymalnie 1 pole w trybie array-contains.
Dzięki indeksowaniu pola tablicy w trybie array-contains silnik zapytań może szybko lokalizować dokumenty zawierające określone wartości tablicy. Bez indeksu zapytania sprawdzają wartości tablicy, wykonując pełne skanowanie kolekcji, co zwiększa czas oczekiwania na zapytanie i koszty odczytu wraz ze wzrostem rozmiaru kolekcji.
Aby można było zindeksować pole tablicy, musi ono spełniać te wymagania:
- Wymaganie dotyczące niepustej tablicy: wpis indeksu jest tworzony tylko wtedy, gdy pole tablicy istnieje w dokumencie i jest niepustą tablicą. Dokumenty z brakującymi polami, polami, które nie są tablicami, lub pustymi polami tablic nie są indeksowane.
Zależność między gęstością a indeksami array-contains
W przypadku indeksów, które zawierają pole array-contains, reguły gęstości indeksu mają zastosowanie tylko do uporządkowanych pól indeksowanych. Jeśli wymaganie dotyczące niepustej tablicy jest spełnione, reguły gęstości mają zastosowanie do pozostałych uporządkowanych pól indeksowanych w indeksie:
- Indeks nierozproszony (
DENSE): dla dokumentu generowany jest wpis indeksu. Wszystkie brakujące uporządkowane pola indeksowane w indeksie są przechowywane we wpisie indeksu jakonull. - Indeks rozproszony (
SPARSE): wpis indeksu jest generowany tylko wtedy, gdy w dokumencie istnieje co najmniej jedno z uporządkowanych indeksowanych pól.
Przykład: generowanie wpisu indeksu
Weź pod uwagę indeks users (tags[*], status ASC):
| Dokument | NON-SPARSE indeks |
SPARSE indeks |
|---|---|---|
{ |
Zindeksowane: • (tagi: "news", stan: "active") |
Zindeksowane: • (tagi: "news", stan: "active") |
{ |
Zindeksowane: • (tagi: "news", stan: "active") • (tagi: "sports", stan: "active") |
Zindeksowane: • (tagi: "news", stan: "active") • (tagi: "sports", stan: "active") |
{ |
Zindeksowano: • (tagi: "news", stan: "active") (usunięto duplikaty) |
Zindeksowano: • (tagi: "news", stan: "active") (usunięto duplikaty) |
{ |
Zindeksowane: • (tagi: null, stan: "active") |
Zindeksowane: • (tagi: null, stan: "active") |
{ |
Zindeksowane: • (tagi: "news", stan: null) |
Nie zindeksowano (brak pola status) |
{ |
Nie zindeksowano (pole nie jest tablicą) | Nie zindeksowano (pole nie jest tablicą) |
{ |
Nie zindeksowano (pole nie jest tablicą) | Nie zindeksowano (pole nie jest tablicą) |
{ |
Nie zindeksowano (brak pola tags) |
Nie zindeksowano (brak pola tags) |
{ |
Not indexed (pusta tablica) | Not indexed (pusta tablica) |
Przykładowe zapytanie
Sieć
// Query for users where 'tags' contains 'news' and 'status' is 'active' const query = db.collection("users") .where("tags", "array-contains", "news") .where("status", "==", "active"); // Documents returned by the query: // [ // { // "id": "alice", // "tags": ["news", "tech"], // "status": "active" // } // ]
Unikalne indeksy
Ustaw opcję unikalnego indeksu, aby wymusić unikalne wartości w zindeksowanych polach. W przypadku indeksów w wielu polach każda kombinacja wartości musi być unikalna w całym indeksie. Baza danych odrzuca wszystkie operacje aktualizacji i wstawiania, które próbują utworzyć wpisy indeksu ze zduplikowanymi wartościami. Jeśli dane w indeksowanych polach zawierają zduplikowane wartości i spróbujesz utworzyć unikalny indeks, jego tworzenie nie powiedzie się, a w szczegółach operacji pojawi się komunikat o błędzie.
Brakujące pola w unikalnym indeksie
Jeśli wstawisz dokument, w którym brakuje pól unikalnego indeksu, indeks ustawi wartości null dla brakujących pól. Wynikowy wpis indeksu musi być unikalny, inaczej operacja się nie powiedzie.
Na przykład w przypadku tego indeksu:
| Kolekcja | Zindeksowane pola | Zakres zapytania |
|---|---|---|
| miejscowości | nazwa (rosnąco), | Kolekcja |
Jeśli dodasz do kolekcji dokument {"abbreviation": "LA"}, unikalny indeks utworzy wpis z polem name ustawionym na null. Jeśli spróbujesz dodać dokument {"abbreviation": "NYC"}, operacja się nie powiedzie, ponieważ wynikowy wpis w unikalnym indeksie będzie taki sam.
To samo dotyczy unikalnych indeksów z wieloma polami.
Podczas tworzenia lub aktualizowania dokumentu brakujące pola indeksowane są ustawiane na null, a wynikowy wpis indeksu musi być unikalny w indeksie.
Unikalne indeksy wartości tablicowych
Unikalny indeks array-contains uniemożliwia tworzenie dokumentów z nakładającymi się elementami tablicy.
Ten typ indeksu nie wymaga, aby tablica miała unikalne wartości w jednym dokumencie.
Na przykład w przypadku unikalnego indeksu w polu o nazwie tags:
Możesz wstawić ten dokument (doc1):
{
"tags": [ "news", "tech", "news", "music" ]
}
Indeks zezwala na zduplikowane wartości ("news") w tej samej tablicy pojedynczego dokumentu.
Jeśli spróbujesz wstawić drugi dokument, doc2, ze zduplikowanym elementem, operacja się nie powiedzie:
{
"tags": [ "sports", "music" ]
}
Operacja nie powiedzie się, ponieważ "music" jest już obecny w tablicy doc1 i zmapowany w indeksie.
Jeśli chcesz mieć pewność, że elementy w tej samej tablicy w jednym dokumencie są unikalne, obsłuż to w logice aplikacji.
Puste tablice, brakujące pola i wartości null
Zwykle brakujące pola w unikalnym indeksie są traktowane jako null i muszą być unikalne w dokumentach (patrz Brakujące pola w unikalnym indeksie).
Jednak w przypadku indeksów unikalnych w polach tablicy:
- Puste tablice, brakujące pola i samodzielne wartości null: jeśli pole tablicy jest puste, całkowicie go brakuje lub zawiera samodzielną wartość
null(nie w tablicy), dla dokumentu nie są generowane żadne klucze indeksu. Dlatego wiele dokumentów może mieć puste pola lub samodzielne wartościnullbez wywoływania błędów zduplikowanych kluczy. - Elementy o wartości null w tablicy: jeśli tablica zawiera element o wartości
null(np.["news", null]), elementnulljest indeksowany. Każdy kolejny dokument zawierający elementnullw polu tablicy indeksowanej spowoduje błąd zduplikowanego klucza.
Rozwiązywanie problemów z błędami tworzenia indeksu
Podczas zarządzania indeksami mogą wystąpić błędy ich tworzenia. Operacja indeksowania może się nie powieść, jeśli baza danych napotka problem z danymi. Operacje indeksowania mogą się nie powieść z tych powodów:
- Osiągnięto limit indeksu. Na przykład operacja mogła osiągnąć maksymalną liczbę wpisów indeksu na dokument. Jeśli utworzenie indeksu się nie powiedzie, zobaczysz komunikat o błędzie. Jeśli limit indeksów nie został osiągnięty, spróbuj ponownie wykonać operację indeksowania.
- Ustawiono opcję unikalnego indeksu, a dane z indeksowanych pól utworzyłyby zduplikowane wpisy indeksu. Aby przejść dalej, usuń z danych zduplikowane kombinacje wartości.
Co dalej?
Dowiedz się, jak tworzyć indeksy i nimi zarządzać.