Udostępnij przez


Najlepsze rozwiązania dotyczące indeksowania w usłudze Azure DocumentDB

Pola z możliwością wykonywania zapytań powinny zawsze mieć utworzone indeksy

Operacje odczytu na podstawie predykatów i agregacji skonsultuj się z indeksem odpowiadających im filtrów. W przypadku braku indeksów aparat bazy danych przeprowadza skanowanie dokumentów w celu pobrania pasujących dokumentów. Skanowanie jest zawsze kosztowne i coraz droższe w miarę wzrostu ilości danych w kolekcji. Aby uzyskać optymalną wydajność zapytań, indeksy powinny być zawsze tworzone dla wszystkich pól z możliwością wykonywania zapytań.

Unikaj niepotrzebnych indeksów i indeksowania wszystkich pól domyślnie

Indeksy powinny być tworzone tylko dla pól z możliwością wykonywania zapytań. Indeksowanie symboli wieloznacznych powinno być używane tylko wtedy, gdy wzorce zapytań są nieprzewidywalne, gdy dowolne pole w strukturze dokumentu może być częścią filtrów zapytań.

Wskazówka

Usługa Azure DocumentDB domyślnie indeksuje tylko pole _id. Wszystkie inne pola nie są domyślnie indeksowane. Pola do indeksowania powinny być planowane z wyprzedzeniem, aby zmaksymalizować wydajność zapytań, jednocześnie minimalizując wpływ na operacje zapisu związany z indeksowaniem zbyt wielu pól.

Po wstawieniu nowego dokumentu po raz pierwszy lub zaktualizowaniu lub usunięciu istniejącego dokumentu każdy z określonych pól w indeksie jest również aktualizowany. Jeśli zasady indeksowania zawierają dużą liczbę pól (lub wszystkich pól w dokumencie), więcej zasobów jest zużywanych przez serwer podczas aktualizowania odpowiednich indeksów. W przypadku uruchamiania na dużą skalę należy indeksować tylko pola z możliwością wykonywania zapytań, podczas gdy wszystkie pozostałe pola, które nie są używane w predykatach zapytań, powinny pozostać wykluczone z indeksu.

Strategia indeksowania na potrzeby wydajnego pozyskiwania danych

W przypadku migracji dużych obciążeń do usługi Azure DocumentDB zaleca się utworzenie indeksów po załadowaniu danych w celu wydajnego wykonywania. Znacznie zmniejsza to obciążenie zapisu, minimalizuje zużycie zasobów i przyspiesza wydajność pozyskiwania danych. Utrzymywanie indeksów podczas importu zbiorczego może spowolnić operacje wstawiania, ponieważ każda operacja zapisu musi zaktualizować wszystkie odpowiednie indeksy.

Aby utworzyć wiele indeksów na danych historycznych, należy wydać niewyłączające polecenia createIndex dla każdego pola.

Nie zawsze można zaplanować wszystkie wzorce zapytań z góry, szczególnie w miarę rozwoju wymagań aplikacji. Zmiana aplikacji wymaga nieuchronnie dodania pól do indeksu w klastrze z dużą ilością danych historycznych.

W takich scenariuszach każde polecenie createIndex powinno być wystawiane asynchronicznie bez oczekiwania na odpowiedź z serwera.

Uwaga / Notatka

Domyślnie usługa Azure DocumentDB odpowiada na operację createIndex dopiero po pełnym utworzeniu indeksu na podstawie danych historycznych. W zależności od rozmiaru klastra i ilości pozyskanych danych może to zająć trochę czasu i pojawić się tak, jakby serwer nie odpowiada na polecenie createIndex.

Jeśli polecenia createIndex są wydawane za pośrednictwem powłoki Mongo, użyj Ctrl + C, aby przerwać polecenie, aby zatrzymać oczekiwanie na odpowiedź i wydać następny zestaw operacji.

Uwaga / Notatka

Użycie Ctrl + C w celu przerwania polecenia createIndex po jego wydaniu nie kończy operacji kompilacji indeksu na serwerze. Po prostu uniemożliwia usłudze Shell oczekiwanie na odpowiedź z serwera, podczas gdy serwer asynchronicznie kontynuuje kompilowanie indeksu w istniejących dokumentach.

Tworzenie indeksów złożonych dla zapytań z predykatami w wielu polach

Indeksy złożone powinny być używane w następujących scenariuszach:

  • Zapytania z filtrami w wielu polach
  • Zapytania z filtrami na wielu polach i z jednym lub więcej polami posortowanymi w kolejności rosnącej lub malejącej

Rozważmy następujący dokument w bazie danych 'cosmicworks' i kolekcji 'pracowników'

{
    "firstName": "Steve",
    "lastName": "Smith",
    "companyName": "Microsoft",
    "division": "Azure",
    "subDivision": "Data & AI",
    "timeInOrgInYears": 7
}

Rozważ następujące zapytanie, aby znaleźć wszystkich pracowników o nazwisku "Smith", którzy są w organizacji od ponad pięciu lat:

db.employee.find({"lastName": "Smith", "timeInOrgInYears": {"$gt": 5}})

Indeks złożony zarówno dla wartości "lastName", jak i "timeInOrgInYears" optymalizuje to zapytanie:

use cosmicworks;
db.employee.createIndex({"lastName" : 1, "timeInOrgInYears" : 1})

Śledzenie stanu operacji createIndex

Gdy indeksy są dodawane, a dane historyczne muszą być indeksowane, postęp operacji kompilacji indeksu można śledzić przy użyciu polecenia db.currentOp().

Rozważ ten przykład, aby śledzić postęp indeksowania w bazie danych 'cosmicworks'.

use cosmicworks;
db.currentOp()

Gdy operacja createIndex jest w toku, odpowiedź wygląda następująco:

{
  "inprog": [
    {
      "shard": "defaultShard",
      "active": true,
      "type": "op",
      "opid": "30000451493:1719209762286363",
      "op_prefix": 30000451493,
      "currentOpTime": "2024-06-24T06:16:02.000Z",
      "secs_running": 0,
      "command": { "aggregate": "" },
      "op": "command",
      "waitingForLock": false
    },
    {
      "shard": "defaultShard",
      "active": true,
      "type": "op",
      "opid": "30000451876:1719209638351743",
      "op_prefix": 30000451876,
      "currentOpTime": "2024-06-24T06:13:58.000Z",
      "secs_running": 124,
      "command": { "createIndexes": "" },
      "op": "workerCommand",
      "waitingForLock": false,
      "progress": {},
      "msg": ""
    }
  ],
  "ok": 1
}

Domyślnie włącz duże klucze indeksu

Nawet jeśli dokumenty nie zawierają kluczy, które mają dużą liczbę znaków lub dokumenty nie zawierają wielu poziomów zagnieżdżania, określenie dużych kluczy indeksu gwarantuje, że te scenariusze są objęte. Teraz duży klucz indeksowy jest domyślnym zachowaniem silnika.

Aby włączyć duże klucze indeksu, posłużmy się następującym przykładem w kolekcji "large_index_coll" w bazie danych "cosmicworks".

use cosmicworks;
db.runCommand(
{
 "createIndexes": "large_index_coll",
 "indexes": [
    {
        "key": { "ikey": 1 },
        "name": "ikey_1",
        "enableLargeIndexKeys": true
    }
    ]
})

Priorytetowe traktowanie tworzenia indeksów przed nowymi operacjami zapisu z użyciem opcji blokowania

W przypadku scenariuszy, w których indeks powinien zostać utworzony przed załadowaniem danych, należy użyć opcji blokowania do blokowania przychodzących zapisów do momentu zakończenia kompilacji indeksu.

Ustawienie { "blocking": true } jest przydatne w narzędziach migracji, w których indeksy są tworzone w pustych kolekcjach przed rozpoczęciem zapisu danych.

Rozważmy przykład opcji blokowania tworzenia indeksu w kolekcji "employee" w bazie danych "cosmicworks":

use cosmicworks;
db.runCommand({
  createIndexes: "employee",
  indexes: [{"key":{"name":1}, "name":"name_1"}],
  blocking: true
})

Zapoznaj się z indeksowaniem tekstu, co umożliwia efektywne wyszukiwanie i wykonywanie zapytań dotyczących danych tekstowych.

Następny krok