View a markdown version of this page

쿼리 실행 속도가 느림 - Amazon DocumentDB

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

쿼리 실행 속도가 느림

식별 - 문제 발견

느리게 실행되는 쿼리는 비즈니스 요구 사항에 필요한 실행 시간을 초과하는 쿼리입니다. 느린 쿼리를 구성하는 항목의 정의는 워크로드마다 다릅니다. 프로파일러 로그 또는 성능 개선 도우미를 통해 느린 쿼리를 식별할 수 있습니다.

  1. 아직 활성화되지 않은 경우 프로파일러를 활성화합니다. 프로파일러 로그는 로그 그룹:에서 Amazon CloudWatch에 기록됩니다/aws/docdb/<cluster-identifier>/profiler. CloudWatch Logs Insights를 사용하여 쿼리합니다.

    ecommerce.products 컬렉션에 대한 가장 느린 쿼리 10개를 가져오는 CloudWatch 로그 분석 쿼리의 :

    filter ns="ecommerce.products" | sort millis desc | limit 10
  2. 성능 개선 도우미를 사용하여 거의 실시간으로 비용이 많이 드는 쿼리를 식별할 수 있습니다. 아직 활성화되지 않은 경우 성능 개선 도우미를 활성화합니다.

    1. AWS 콘솔을 열고 Amazon DocumentDB로 이동한 다음 성능 개선 도우미로 이동하여 클러스터 인스턴스를 선택합니다.

    2. DB 로드(AAS) 타임라인과 상위 쿼리(DB 로드 기준)를 검토합니다. 쿼리 다이제스트를 확장하여 리터럴 하위 문을 봅니다.

    3. 분석이 필요한 쿼리를 캡처합니다.

    참고

    성능 개선 도우미의 모든 쿼리가 비효율적이거나 느린 쿼리는 아닙니다.

조사 - 정보 수집

  1. 프로파일러는 밀리스, 반환 및 planSummary(인덱스 사용)를 포함하여 쿼리 실행 계획과 이와 관련된 주요 지표를 제공합니다.

    { "op": "query", "ts": 1721374275673, "ns": "test.perf", "command": { "find": "perf", "filter": { "threadRunCount": 0 }, "$db": "test", "lsid": { "id": { "$binary": "oO2wEtpgQIK+y9KGByYnsw==", "$type": "4" } }, "$readPreference": { "mode": "secondaryPreferred" } }, "cursorExhausted": true, "nreturned": 0, "responseLength": 0, "protocol": "op_query", "millis": 137, "planSummary": "IXSCAN", "execStats": { "stage": "FETCH", "nReturned": "0", "executionTimeMillisEstimate": "100.346", "inputStage": { "stage": "IXSCAN", "nReturned": "0", "executionTimeMillisEstimate": "100.342", "indexName": "threadRunCount_1" } }, "client": "172.31.6.165:43154", "appName": "ProdAppTester14", "user": "adminuser" }

    COLLSCAN 쿼리를 찾으려면:

    filter planSummary="COLLSCAN" | sort millis desc | limit 20
  2. 성능 개선 도우미를 사용하여 대기, 로드 및 리소스 영향(예: 쿼리당 IOPS 또는 CPU)과 같은 쿼리 실행 추세를 실시간으로 분석할 수 있습니다.

    성능 개선 도우미는 쿼리 실행 계획을 제공하지 않으므로 쿼리를 캡처하고 Amazon DocumentDB 클러스터의 쿼리에 대한 설명("executionStats")을 실행합니다.

    db.ecommerce.products.find().explain("executionStats")
  3. 선택적으로 프로파일러 지표를 성능 개선 도우미 데이터와 연관시킵니다(예: 프로파일러의 상위 쿼리와 성능 개선 도우미의 상위 쿼리 일치).

진단 - 근본 원인 찾기

이 단계에서는 쿼리 계획을 진단하여 잠재적 최적화를 식별합니다. 다음 흐름 사용 - 증상 → 가능한 원인:

  • 증상: planSummary: "COLLSCAN"

    원인: 인덱스가 누락되었거나 잘못되었습니다.

  • 증상: $group / $sort에서 집계 속도가 느림

    원인: 집계 파이프라인이 메모리에서 너무 많은 데이터를 처리하고 있을 수 있습니다.

  • 증상: 인덱스가 사용되지만 성능 개선 도우미는 IO 대기별로 그룹화된 DB 로드를 표시하는 동안 지연 시간이 깁니다(planSummary: "IXSCAN").

    원인: I/O 바인딩된 쿼리. 인덱스 또는 작업 세트가 인스턴스에서 사용 가능한 버퍼 캐시를 초과합니다.

  • 증상: PI는 CPU 대기 상태, 쿼리가 적기 때문에 높은 AAS를 표시합니다.

    원인: CPU 바운드 쿼리(복잡한 집계, $regex).

  • 증상: 느린 쿼리가 많지만 비용이 많이 드는 planSummary를 보여주는 쿼리가 없음

    원인: 외부 병목 현상(네트워크, 제한, 유지 관리 작업, 쿼리 볼륨).

해결 - 문제 해결

수정 사항을 구현할 때는 항상 explain("executionStats")로 확인하고 성능 개선 도우미 DB 로드를 모니터링합니다.

  1. planSummary: "COLLSCAN"

    • 대상 인덱스를 생성합니다.

      예: { 범주, 가격 }을 기준으로 필터링하고 가격 내림차순으로 정렬하는 빈번한 쿼리의 경우:

      db.products.createIndex({ category: 1, price: -1 })
  2. $group/$sort로 집계 속도가 느림

    • $match 및 $project를 조기에 푸시하여 $group / $sort로 흐르는 문서를 줄입니다.

    • 파이프라인 초기에 필드 수를 제한합니다.

      db.products.explain("executionStats").aggregate([ { $match: { category: "Electronics", price: { $gt: 0 } } }, // early filter { $project: { price: 1, category: 1 } }, // reduce document size { $group: { _id: "$category", avgPrice: { $avg: "$price" } } } ])
  3. 성능 개선 도우미가 IO 대기별로 그룹화된 DB 로드를 표시하는 동안 지연 시간이 높음

    • BufferCacheHitRatio가 낮은지 또는 인스턴스의 ReadIOPS가 높은지 확인합니다. 인스턴스 메모리를 늘리거나(인스턴스 클래스 업그레이드, 예: r6g.large → r6g.xlarge) NVMe 인스턴스 클래스를 사용합니다.

    • 인덱스 공간을 줄입니다.

    • 읽기 전용 복제본을 추가하여 읽기 트래픽을 오프로드합니다(쿼리가 최종 일관성으로 허용 가능한 경우 readPreference 설정을 사용하여 복제본의 트래픽을 리디렉션).

  4. PI는 CPU 대기 상태, 쿼리가 적기 때문에 높은 AAS를 표시합니다.

    • 값비싼 $regex를 인덱싱된 접두사 검색 또는 $text 인덱스로 바꿉니다.

    • 배치 쓰기(삽입)를 통해 쓰기 증폭을 줄입니다.

참고

변경 사항을 프로덕션으로 승격하기 전에 항상 하위 환경(비프로덕션)에서 변경 사항을 테스트합니다.