На этой странице приведены примеры стратегии индексации, которую можно использовать для запросов с фильтрами диапазона и неравенства по нескольким полям для создания эффективного процесса запроса.
Прежде чем оптимизировать свои запросы, ознакомьтесь с соответствующими концепциями .
Оптимизируйте запросы с помощью Query Explain
Чтобы определить, оптимальны ли ваш запрос и индексы, вы можете использовать Query Explain для получения сводки плана запроса и статистики выполнения запроса:
Ява
Query q = db.collection("employees").whereGreaterThan("salary",
100000).whereGreaterThan("experience", 0);
ExplainResults<QuerySnapshot> explainResults = q.explain(ExplainOptions.builder().analyze(true).build()).get();
ExplainMetrics metrics = explainResults.getMetrics();
PlanSummary planSummary = metrics.getPlanSummary();
ExecutionStats executionStats = metrics.getExecutionStats();
System.out.println(planSummary.getIndexesUsed());
System.out.println(stats.getResultsReturned());
System.out.println(stats.getExecutionDuration());
System.out.println(stats.getReadOperations());
System.out.println(stats.getDebugStats());
Node.js
let q = db.collection("employees")
.where("salary", ">", 100000)
.where("experience", ">",0);
let options = { analyze : 'true' };
let explainResults = await q.explain(options);
let planSummary = explainResults.metrics.planSummary;
let stats = explainResults.metrics.executionStats;
console.log(planSummary);
console.log(stats);
В следующем примере показано, как использование правильного порядка индекса сокращает количество записей индекса, сканируемых Cloud Firestore .
Простые запросы
В предыдущем примере с набором сотрудников простой запрос, который выполняется с индексом (experience ASC, salary ASC)
выглядит следующим образом:
Ява
db.collection("employees")
.whereGreaterThan("salary", 100000)
.whereGreaterThan("experience", 0)
.orderBy("experience")
.orderBy("salary");
Запрос сканирует 95000 записей индекса только для возврата пяти документов. Поскольку предикат запроса не удовлетворен, большое количество записей индекса считывается, но отфильтровывается.
// Output query planning info { "indexesUsed": [ { "properties": "(experience ASC, salary ASC, __name__ ASC)", "query_scope": "Collection" } ], // Output Query Execution Stats "resultsReturned": "5", "executionDuration": "2.5s", "readOperations": "100", "debugStats": { "index_entries_scanned": "95000", "documents_scanned": "5", "billing_details": { "documents_billable": "5", "index_entries_billable": "95000", "small_ops": "0", "min_query_cost": "0" } } }
Из экспертных знаний в области вы можете сделать вывод, что большинство сотрудников будут иметь хотя бы некоторый опыт, но лишь немногие будут иметь зарплату более 100000. Учитывая это понимание, вы можете увидеть, что ограничение salary
более избирательно, чем ограничение experience
. Чтобы повлиять на индекс, который Cloud Firestore использует для выполнения запроса, укажите предложение orderBy
, которое упорядочивает ограничение salary
перед ограничением experience
.
Ява
db.collection("employees")
.whereGreaterThan("salary", 100000)
.whereGreaterThan("experience", 0)
.orderBy("salary")
.orderBy("experience");
Когда вы явно используете предложение orderBy()
для добавления предикатов, Cloud Firestore использует индекс (salary ASC, experience ASC)
для выполнения запроса. Поскольку селективность первого фильтра диапазона в этом запросе выше по сравнению с предыдущим запросом, запрос выполняется быстрее и является более экономичным.
// Output query planning info { "indexesUsed": [ { "properties": "(salary ASC, experience ASC, __name__ ASC)", "query_scope": "Collection" } ], // Output Query Execution Stats "resultsReturned": "5", "executionDuration": "0.2s", "readOperations": "6", "debugStats": { "index_entries_scanned": "1000", "documents_scanned": "5", "billing_details": { "documents_billable": "5", "index_entries_billable": "1000", "small_ops": "0", "min_query_cost": "0" } } }
Что дальше?
- Узнайте больше о Query Explain .
- Узнайте о передовых методах индексации .