Query Explain을 사용한 쿼리 성능 이해

Query Explain을 사용하면 Cloud Firestore 쿼리를 백엔드에 제출하고 그 대가로 백엔드 쿼리 실행에 대한 자세한 성능 통계를 받을 수 있습니다. 이는 여러 관계형 데이터베이스 시스템에서 EXPLAIN [ANALYZE] 작업과 같은 기능을 합니다.

Query Explain 요청은 Firestore 서버 클라이언트 라이브러리를 사용하여 보낼 수 있습니다.

Query Explain 결과는 쿼리가 실행되는 방식을 이해하는 데 도움이 되므로 비효율성과 서버 측 병목 현상이 발생할 가능성이 있는 위치를 보여줍니다.

Query Explain:

  • 쿼리 색인을 조정하고 효율성을 높일 수 있도록 쿼리 계획 단계에 대한 유용한 정보를 제공합니다.
  • 분석 옵션을 사용하면 쿼리별로 비용 및 성능을 파악하는 데 도움이 되므로 이를 통해 다양한 쿼리 패턴을 빠르게 반복하여 사용량을 최적화할 수 있습니다.

Query Explain 옵션 이해: 기본 및 분석

Query Explain 작업은 기본 옵션 또는 분석 옵션을 사용하여 수행할 수 있습니다.

기본 옵션을 사용하면 Query Explain에서 쿼리를 계획하고 실행 단계를 건너뜁니다. 그러면 플래너 단계 정보가 반환됩니다. 이를 사용하여 쿼리에 필요한 색인이 있는지 확인하고 어떤 색인이 사용되는지 파악할 수 있습니다. 예를 들어 특정 쿼리가 여러 색인을 교차할 필요 없이 복합 색인을 사용하고 있는지 확인하는 데 도움이 됩니다.

분석 옵션을 사용하면 Query Explain에서 쿼리를 계획하고 실행합니다. 그러면 쿼리 실행 런타임의 통계와 함께 앞에서 언급한 모든 플래너 정보가 반환됩니다. 여기에는 쿼리의 결제 정보와 쿼리 실행에 대한 시스템 수준 통계가 포함됩니다. 이 도구를 사용하면 다양한 쿼리 및 색인 구성을 테스트하여 비용과 지연 시간을 최적화할 수 있습니다.

Query Explain의 비용

기본 옵션으로 Query Explain을 사용하면 색인 또는 읽기 작업이 수행되지 않습니다. 쿼리 복잡성과 관계없이 읽기 작업 1회에 대한 요금이 청구됩니다.

분석 옵션으로 Query Explain을 사용하면 색인 및 읽기 작업이 수행되므로 쿼리에 대한 요금이 평소와 같이 청구됩니다. 분석 활동에 대한 추가 요금은 없으며 실행 중인 쿼리에 대한 일반적인 요금만 청구됩니다.

기본 옵션으로 Query Explain 사용

클라이언트 라이브러리를 사용하여 기본 옵션 요청을 제출할 수 있습니다.

요청은 IAM으로 인증되며, 일반 쿼리 작업에 대한 동일한 권한을 사용합니다. 기타 인증 기술(예: Firebase 인증)은 무시됩니다. 자세한 내용은 서버 클라이언트 라이브러리의 IAM의 가이드를 참조하세요.

자바(관리자)

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 보고서 참조를 참조하세요.

분석 옵션으로 Query Explain 사용

클라이언트 라이브러리를 사용하여 분석 옵션 요청을 제출할 수 있습니다.

요청은 IAM으로 인증되며, 일반 쿼리 작업에 대한 동일한 권한을 사용합니다. 기타 인증 기술(예: Firebase 인증)은 무시됩니다. 자세한 내용은 서버 클라이언트 라이브러리의 IAM의 가이드를 참조하세요.

자바(관리자)

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;

    

다음 예시는 planInfo 외에 반환되는 stats 객체를 보여줍니다. 응답의 정확한 형식은 실행 환경에 따라 다릅니다. 응답 예시는 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",
               }
    }

}

자세한 내용은 Query Explain 보고서 참조를 참조하세요.

결과 해석 및 조정

영화를 장르 및 제작 국가별로 쿼리하는 예시 시나리오를 살펴보겠습니다.

예를 들어 다음 SQL 쿼리와 동일하다고 가정해 보겠습니다.

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

분석 옵션을 사용하는 경우 반환된 측정항목은 2개의 단일 필드 색인 (category ASC, __name__ ASC)(country ASC, __name__ ASC)에서 실행되는 쿼리를 보여줍니다. 16,500개의 색인 항목을 스캔하지만 1,200개의 문서만 반환합니다.

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