Понимание производительности запросов с помощью Query Объяснение

Query Explain позволяет отправлять запросы Cloud Firestore в бэкенд и получать в ответ подробную статистику производительности выполнения бэкенд-запросов. Он функционирует как операция EXPLAIN [ANALYZE] во многих реляционных системах баз данных.

Запросы Query Explain можно отправлять с помощью клиентских библиотек сервера Firestore .

Результаты Query Explain помогают понять, как выполняются ваши запросы, показывая неэффективность и местонахождение вероятных узких мест на стороне сервера.

Запрос Объяснение:

  • Предоставляет информацию о этапе планирования запросов, чтобы вы могли скорректировать индексы запросов и повысить эффективность.
  • Использование опции анализа помогает вам оценить затраты и производительность для каждого запроса и позволяет быстро перебирать различные шаблоны запросов с целью оптимизации их использования.

Понять параметры запроса Explain: по умолчанию и анализировать

Операции «Объяснение запроса» можно выполнять с использованием параметра по умолчанию или параметра анализа .

С опцией по умолчанию Query Explain планирует запрос, но пропускает стадию выполнения. Это вернет информацию о стадии планировщика. Вы можете использовать это, чтобы проверить, что запрос имеет необходимые индексы, и понять, какие индексы используются. Это поможет вам проверить, например, что конкретный запрос использует составной индекс, а не пересекается по многим различным индексам.

С опцией анализа Query Explain и планирует, и выполняет запрос. Это возвращает всю ранее упомянутую информацию планировщика вместе со статистикой из времени выполнения запроса. Это будет включать в себя платежную информацию запроса вместе с системными сведениями о выполнении запроса. Вы можете использовать этот инструментарий для тестирования различных конфигураций запросов и индексов, чтобы оптимизировать их стоимость и задержку.

Сколько стоит Query Explain?

При использовании Query Explain с опцией по умолчанию не выполняются операции индексирования или чтения. Независимо от сложности запроса, взимается плата за одну операцию чтения.

При использовании Query Explain с опцией анализа выполняются операции индексации и чтения, поэтому вы платите за запрос как обычно. Дополнительная плата за аналитическую деятельность не взимается, взимается только обычная плата за выполняемый запрос.

Используйте Query Explain с опцией по умолчанию

Вы можете использовать клиентские библиотеки для отправки запроса на параметры по умолчанию.

Обратите внимание, что запросы аутентифицируются с помощью IAM, используя те же разрешения для обычных операций запроса. Другие методы аутентификации, такие как Firebase Authentication , игнорируются. Для получения дополнительной информации см. руководство по IAM для клиентских библиотек сервера .

Java (Администратор)

Query q = db.collection("col").whereGreaterThan("a", 1);
ExplainOptions options = ExplainOptions.builder().build();

ExplainResults<QuerySnapshot> explainResults = q.explain(options).get();
ExplainMetrics metrics = explainResults.getMetrics();
PlanSummary planSummary = metrics.getPlanSummary();

    
Узел (Администратор)

const q = db.collection('col').where('country', '=', 'USA');
const options = { analyze : 'false' };

const explainResults = await q.explain(options);

const metrics = explainResults.metrics;
const plan = metrics.planSummary;

    

Точный формат ответа зависит от среды выполнения. Возвращаемые результаты могут быть преобразованы в JSON. Например:

{
    "indexes_used": [
        {"query_scope": "Collection", "properties": "(category ASC, __name__ ASC)"},
        {"query_scope": "Collection", "properties": "(country ASC, __name__ ASC)"},
    ]
}

Более подробную информацию см. в справочнике по отчету «Объяснение запроса» .

Используйте Query Explain с опцией анализа

Вы можете использовать клиентские библиотеки для отправки запроса на анализ параметров.

Обратите внимание, что запросы аутентифицируются с помощью IAM, используя те же разрешения для обычных операций запроса. Другие методы аутентификации, такие как Firebase Authentication , игнорируются. Для получения дополнительной информации см. руководство по IAM для клиентских библиотек сервера .

Java (Администратор)

Query q = db.collection("col").whereGreaterThan("a", 1);

ExplainOptions options = ExplainOptions.builder().setAnalyze(true).build();

ExplainResults<QuerySnapshot> explainResults = q.explain(options).get();

ExplainMetrics metrics = explainResults.getMetrics();
PlanSummary planSummary = metrics.getPlanSummary();
List<Map<String, Object>> indexesUsed = planSummary.getIndexesUsed();
ExecutionStats stats = metrics.getExecutionStats();

    
Узел (Администратор)

const q = db.collection('col').where('country', '=', 'USA');

const options = { analyze : 'true' };

const explainResults = await q.explain(options);

const metrics = explainResults.metrics;
const plan = metrics.planSummary;
const indexesUsed = plan.indexesUsed;
const stats = metrics.executionStats;

    

В следующем примере показан объект stats , возвращаемый в дополнение к planInfo . Точный формат ответа зависит от среды выполнения. Пример ответа представлен в формате JSON.

{
    "resultsReturned": "5",
    "executionDuration": "0.100718s",
    "readOperations": "5",
    "debugStats": {
               "index_entries_scanned": "95000",
               "documents_scanned": "5"
               "billing_details": {
                     "documents_billable": "5",
                     "index_entries_billable": "0",
                     "small_ops": "0",
                     "min_query_cost": "0",
               }
    }

}

Более подробную информацию см. в справочнике по отчету «Объяснение запроса» .

Интерпретируйте результаты и внесите коррективы

Давайте рассмотрим пример сценария, в котором мы запрашиваем фильмы по жанру и стране производства.

Для иллюстрации предположим эквивалент этого SQL-запроса.

SELECT *
FROM /movies
WHERE category = 'Romantic' AND country = 'USA';

Если мы используем опцию анализа, возвращаемые метрики показывают, что запрос выполняется на двух индексах с одним полем (category ASC, __name__ ASC) и (country ASC, __name__ ASC) . Он сканирует 16500 записей индекса, но возвращает только 1200 документов.

// Output query planning info
{
    "indexes_used": [
        {"query_scope": "Collection", "properties": "(category ASC, __name__ ASC)"},
        {"query_scope": "Collection", "properties": "(country ASC, __name__ ASC)"},
    ]
}

// Output query status
{
    "resultsReturned": "1200",
    "executionDuration": "0.118882s",
    "readOperations": "1200",
    "debugStats": {
               "index_entries_scanned": "16500",
               "documents_scanned": "1200"
               "billing_details": {
                     "documents_billable": "1200",
                     "index_entries_billable": "0",
                     "small_ops": "0",
                     "min_query_cost": "0",
               }
    }
}

Для оптимизации производительности выполнения запроса можно создать полностью покрытый составной индекс (category ASC, country ASC, __name__ ASC) .

Запустив запрос еще раз с опцией анализа, мы увидим, что для этого запроса выбран вновь созданный индекс, и запрос выполняется гораздо быстрее и эффективнее.

// Output query planning info
{
    "indexes_used": [
        {"query_scope": "Collection", "properties": "(category ASC, country ASC,  __name__ ASC)"}
    ]
}

// Output query stats
{
    "resultsReturned": "1200",
    "executionDuration": "0.026139s",
    "readOperations": "1200",
    "debugStats": {
               "index_entries_scanned": "1200",
               "documents_scanned": "1200"
               "billing_details": {
                     "documents_billable": "1200",
                     "index_entries_billable": "0",
                     "small_ops": "0",
                     "min_query_cost": "0",
               }
    }
}