Query Объяснение позволяет отправлять запросы Cloud Firestore на серверную часть и получать взамен подробную статистику производительности при выполнении внутренних запросов. Во многих системах реляционных баз данных она функционирует аналогично операции EXPLAIN [ANALYZE]
.
Запросы Query Объяснение можно отправлять с помощью клиентских библиотек сервера Firestore .
Результаты запроса объяснения помогут вам понять, как выполняются ваши запросы, показывая неэффективность и расположение вероятных узких мест на стороне сервера.
Объяснение запроса:
- Предоставляет информацию на этапе планирования запросов, чтобы вы могли корректировать индексы запросов и повышать эффективность.
- Использование опции анализа помогает вам понять ваши затраты и производительность для каждого запроса и позволяет быстро перебирать различные шаблоны запросов, чтобы оптимизировать их использование.
Общие сведения о параметрах объяснения запроса: по умолчанию и анализе
Операции объяснения запроса можно выполнять с использованием параметра по умолчанию или параметра анализа .
При использовании опции по умолчанию Query Объяснение планирует запрос, но пропускает этап выполнения. Это вернет информацию об этапе планирования. Вы можете использовать это, чтобы проверить наличие в запросе необходимых индексов и понять, какие индексы используются. Это поможет вам, например, убедиться, что конкретный запрос использует составной индекс, а не пересекаться по множеству разных индексов.
Благодаря опции анализа Query Объяснение планирует и выполняет запрос. Это возвращает всю ранее упомянутую информацию планировщика вместе со статистикой из среды выполнения запроса. Сюда будет включена информация о выставлении счетов по запросу, а также информация о выполнении запроса на уровне системы. Вы можете использовать этот инструмент для тестирования различных конфигураций запросов и индексов, чтобы оптимизировать их стоимость и задержку.
Сколько стоит объяснение запроса?
Если вы используете объяснение запроса с параметром по умолчанию, операции индексирования или чтения не выполняются. Независимо от сложности запроса тарифицируется одна операция чтения.
Когда вы используете объяснение запроса с параметром анализа, выполняются операции индексирования и чтения, поэтому за запрос взимается обычная плата. Дополнительная плата за аналитическую деятельность не взимается, только обычная плата за выполнение запроса.
Используйте объяснение запроса с опцией по умолчанию.
Вы можете использовать клиентские библиотеки для отправки запроса опций по умолчанию.
Обратите внимание, что запросы аутентифицируются с помощью 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)"}, ] }
Дополнительную информацию см. в справке по отчету «Объяснение запроса» .
Используйте объяснение запроса с опцией анализа.
Вы можете использовать клиентские библиотеки для отправки запроса на вариант анализа.
Обратите внимание, что запросы аутентифицируются с помощью 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", } } }