여러 필드에서 범위 및 불일치 필터를 사용하여 쿼리 최적화

이 페이지에서는 효율적인 쿼리 경험을 만들기 위해 여러 필드에 범위 및 불일치 필터가 있는 쿼리에 사용해야 하는 색인 생성 전략의 예시를 제공합니다.

쿼리를 최적화하기 전에 관련 개념을 읽어보세요.

Query Explain으로 쿼리 최적화

사용된 쿼리와 색인이 최적의 상태인지 확인하기 위해 Query Explain을 사용하여 쿼리의 쿼리 계획 요약 및 실행 통계를 가져올 수 있습니다.

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);

다음 예시는 올바른 색인 순서를 사용하여 Cloud Firestore에서 스캔하는 색인 항목 수를 줄이는 방법을 설명합니다.

간단한 쿼리

직원 컬렉션의 이전 예시에서 (experience ASC, salary ASC) 색인을 사용해 실행되는 간단한 쿼리는 다음과 같습니다.

Java

db.collection("employees")
  .whereGreaterThan("salary", 100000)
  .whereGreaterThan("experience", 0)
  .orderBy("experience")
  .orderBy("salary");

이 쿼리는 95,000개의 색인 항목을 스캔하여 5개 문서만 반환합니다. 쿼리 조건자가 충족되지 않으므로 많은 수의 색인 항목이 읽히지만 필터링됩니다.

// 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"
        }
    }
}

대부분의 직원이 어느 정도 경험을 갖췄지만 급여가 100,000을 초과하는 직원은 거의 없을 것이라는 사실을 분야별 전문 지식에서 추론할 수 있습니다. 이 통계를 바탕으로 salary 제약 조건이 experience 제약 조건보다 더 선택적이라고 결론을 내릴 수 있습니다. Cloud Firestore에서 쿼리를 실행하는 데 사용하는 색인에 영향을 주려면 salary 제약조건을 experience 제약조건보다 먼저 정렬하는 orderBy 절을 지정합니다.

Java

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"
        }
    }
}

다음 단계