Otimize as consultas com filtros de intervalo e de desigualdade em vários campos
Esta página oferece exemplos de estratégias de indexação que pode usar para consultas com filtros de intervalo e desigualdade em vários campos para criar uma experiência de consulta eficiente.
Antes de otimizar as suas consultas, leia acerca dos conceitos relacionados.
Otimize consultas com a explicação de consultas
Para determinar se a sua consulta e os seus índices são ideais, pode usar o comando Query Explain para obter o resumo do plano de consulta e as estatísticas de execução da consulta:
Java
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);
O exemplo seguinte mostra como a utilização da ordem correta dos índices reduz o número de entradas de índice que o Firestore analisa.
Consultas simples
Com o exemplo anterior de uma coleção de funcionários, a consulta simples que é executada com o índice (experience ASC, salary ASC)
é a seguinte:
Java
db.collection("employees")
.whereGreaterThan("salary", 100000)
.whereGreaterThan("experience", 0)
.orderBy("experience")
.orderBy("salary");
A consulta analisa 95 000 entradas de índice apenas para devolver cinco documentos. Uma vez que o predicado de consulta não é satisfeito, é lido um grande número de entradas de índice, mas são filtradas.
// 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" } } }
Pode inferir a partir dos conhecimentos do domínio que a maioria dos funcionários tem, pelo menos, alguma experiência, mas poucos têm um salário superior a 100 000. Tendo em conta esta estatística, pode ver que a restrição salary
é mais seletiva do que a restrição experience
. Para influenciar o índice que o Firestore usa para executar a consulta, especifique uma cláusula orderBy
que ordene a restrição salary
antes da restrição experience
.
Java
db.collection("employees")
.whereGreaterThan("salary", 100000)
.whereGreaterThan("experience", 0)
.orderBy("salary")
.orderBy("experience");
Quando usa explicitamente a cláusula orderBy()
para adicionar os predicados, o Firestore usa o índice (salary ASC, experience ASC)
para executar a consulta.
Uma vez que a seletividade do primeiro filtro de intervalo é superior nesta consulta em comparação com a consulta anterior, a consulta é executada mais rapidamente e é mais rentável.
// 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" } } }
O que se segue?
- Saiba mais sobre o Query Explain.
- Saiba mais acerca das práticas recomendadas de indexação.