Analizowanie wykonywania zapytań za pomocą funkcji Query Explain

Na tej stronie opisujemy, jak podczas wykonywania zapytania pobrać informacje o jego wykonaniu.

Korzystanie z wyjaśnienia zapytania

Możesz użyć funkcji wyjaśniania zapytań, aby dowiedzieć się, jak są wykonywane zapytania. Zawiera on szczegółowe informacje, które możesz wykorzystać do optymalizacji zapytań.

Z funkcji wyjaśniania zapytań możesz korzystać w konsoli Google Cloud lub za pomocą polecenia explain.

Konsola

Wykonaj zapytanie w edytorze zapytań i otwórz kartę Wyjaśnienie:

  1. W konsoli Google Cloud otwórz stronę Bazy danych.

    Otwórz stronę Bazy danych

  2. Z listy baz danych wybierz bazę danych Cloud Firestore. Konsola Google Cloud otworzy Eksplorator Firestore dla tej bazy danych.
  3. Wpisz zapytanie w edytorze zapytań i kliknij Uruchom.
  4. Kliknij kartę Wyjaśnienie, aby wyświetlić dane wyjściowe analizy zapytania.

    Karta Wyjaśnienie zapytania w konsoli
MongoDB API

Wyjaśnienie zapytania w interfejsie MongoDB API jest obsługiwane za pomocą polecenia explain, którego można używać w narzędziach takich jak Mongo Shell i Compass.

Polecenie explain jest obsługiwane w przypadku poleceń aggregate, find, distinct i count, na przykład:

db.collection.explain('executionStats').find(...)

Możesz też użyć metody explain(), na przykład:

db.collection.find({QUERY}).explain('executionStats')
Ograniczenia
Zwróć uwagę na te ograniczenia i różnice:
  • Wyjaśnienie zapytania nie obsługuje poleceń, które zwracają kursor. Na przykład wywołanie wyjaśnienia przez bezpośrednie wywołanie tego polecenia nie jest obsługiwane:

    db.collection.aggregate(..., explain: true)
  • Wyjaśnienie zapytania jest obsługiwane tylko w przypadku poleceń find, aggregate, count, distinct, update, delete i findAndModify.

  • Wyjaśnienie zapytania obsługuje tryby szczegółowości executionStats, allPlansExecution i queryPlanner.

    • queryPlanner: zwraca tylko plan wykonania, bez wykonywania zapytania;
    • executionStats i allPlansExecution: zwraca plan wykonania wraz ze statystykami rozliczeń, pamięci i wykonania.

    Jeśli nie określono trybu szczegółowości, powłoka domyślnie używa trybu queryPlanner. Aby wyświetlić pełne statystyki wykonywania, musisz określić tryb szczegółowości executionStats lub allPlansExecution.

Analiza

Dane wyjściowe funkcji wyjaśniania zapytań zawierają 2 główne komponenty: statystyki podsumowujące i drzewo wykonywania. Rozważmy to zapytanie jako przykład:

db.orders.aggregate(
 [
   { "$match": { "user_id": 1234 } },
   { "$sort": { "date_placed": 1 } }
 ]
)

Statystyki podsumowania

U góry wyjaśnionych danych wyjściowych znajduje się podsumowanie statystyk wykonania. Użyj tych statystyk, aby określić, czy zapytanie ma długi czas oczekiwania lub wysoki koszt. Zawiera też statystyki pamięci, które informują, jak blisko limitów pamięci jest zapytanie.

Execution:
 results returned: 35
 query id: 7e7b37ea1a259d79
 request peak memory usage: 45.56 KiB (46,656 B)
 data bytes read: 24.58 KiB (25,175 B)
 entity row scanned: 265

Billing:
 read units: 7

Drzewo wykonywania

Drzewo wykonywania opisuje wykonywanie zapytania jako serię węzłów. Węzły dolne (węzły liści) pobierają dane z warstwy pamięci masowej, które przechodzą w górę drzewa, aby wygenerować odpowiedź na zapytanie.

Szczegółowe informacje o każdym węźle wykonywania znajdziesz w dokumentacji dotyczącej wykonywania.

Szczegółowe informacje o tym, jak wykorzystać te informacje do optymalizacji zapytań, znajdziesz w artykule Optymalizacja wykonywania zapytań.

Oto przykład drzewa wykonywania:

Execution:
 results returned: 35
 query id: 7e7b37ea1a259d79
 request peak memory usage: 45.56 KiB (46,656 B)
 data bytes read: 24.58 KiB (25,175 B)
 entity row scanned: 265

Billing:
 read units: 7

Tree:
• Compute
|  $out_1: map_set($record_1, "__id__", $__id___1, "__key__", unset)
|  is query result: true
|
|  Execution:
|   records returned: 35
|   latency: 204.87 ms (local 7.64 ms)
|
└── • Compute
    |  $__id___1: _id($__key___2)
    |
    |  Execution:
    |   records returned: 35
    |   latency: 197.23 ms (local 2.04 ms)
    |
    └── • MajorSort
        |  fields: [$v_5 ASC]
        |  output: [$__key___2, $record_1]
        |
        |  Execution:
        |   records returned: 35
        |   latency: 195.20 ms (local 28.42 ms)
        |   peak memory usage: 45.56 KiB (46,656 B)
        |
        └── • Compute
            |  $v_5: offset($v_4, 0L)
            |
            |  Execution:
            |   records returned: 35
            |   latency: 166.78 ms (local 14.84 ms)
            |
            └── • Compute
                |  $v_4: sortPaths(array($date_placed_1), [date_placed ASC])
                |
                |  Execution:
                |   records returned: 35
                |   latency: 151.94 ms (local 5.43 ms)
                |
                └── • TableScan
                       source: **/orders
                       order: STABLE
                       filter: $eq($user_id_1, 1,234)
                       output bindings: {$__key___2=row().__key__, $date_placed_1=row().date_placed, $record_1=row[* - { __create_time__, __update_time__ }](), $user_id_1=row().user_id}
                       output: [$__key___2, $date_placed_1, $record_1]

                       Execution:
                        records returned: 35
                        latency: 146.50 ms
                        data bytes returned: 3.25 KiB (3,325 B)
                        post-filtered rows: 230
                        records scanned: 265
                        data bytes read: 24.58 KiB (25,175 B)

Co dalej?