View a markdown version of this page

쿼리 계획 분석 - Amazon DocumentDB

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

쿼리 계획 분석

설명 계획을 통한 쿼리 계획 분석은 Amazon DocumentDB 쿼리 성능에 대한 필수 인사이트를 제공합니다. executionStats를 사용한 쿼리 계획은 다음을 포함한 주요 지표를 보여줍니다.

  • 단계당 반환된 문서(nReturned)

  • 단계별 실행 시간(executionTimeMillisEstimate)

  • 계획 생성 기간(planningTimeMillis)

개발자는 쿼리 계획 출력을 검사하여 실행 패턴을 분석하고, 인덱스 사용률을 평가하고, 쿼리 파이프라인 단계에서 잠재적 최적화 기회를 식별할 수 있습니다.

쿼리 계획을 분석하려면 다음 형식으로 explain() 명령을 사용할 수 있습니다.

db.runCommand({explain: {query document}, verbosity: "executionStats"}) db.collection.find().explain("executionStats");

다음은 예제 작업입니다.

db.collection.find({ companyname: { '$eq': 'ANYCOMPANY' }, isDeleted: { '$eq': false } }).sort({"createdAt":1}).limit(2).explain("executionStats");

이 작업의 출력은 다음과 같이 표시됩니다.

{ queryPlanner: { plannerVersion: 2, namespace: 'limit_test.test', winningPlan: { stage: 'LIMIT_SKIP', inputStage: { stage: 'SORT', sortPattern: { createdAt: 1 }, inputStage: { stage: 'IXSCAN', indexName: 'companyname_1_createdAt_1_isDeleted_1', direction: 'forward', indexCond: { '$and': [ { companyname: { '$eq': 'ANYCOMPANY' } }, { isDeleted: { '$eq': false } } ] } } } } }, indexFilterSet: false, indexFilterApplied: false, executionStats: { executionSuccess: true, executionTimeMillis: '4.186', planningTimeMillis: '3.909', executionStages: { stage: 'LIMIT_SKIP', nReturned: '2', executionTimeMillisEstimate: '0.199', inputStage: { stage: 'SORT', nReturned: '2', executionTimeMillisEstimate: '0.197', sortPattern: { createdAt: 1 }, inputStage: { stage: 'IXSCAN', nReturned: '34', executionTimeMillisEstimate: '0.151', indexName: 'companyname_1_createdAt_1_isDeleted_1', direction: 'forward', indexCond: { '$and': [ { companyname: { '$eq': 'ANYCOMPANY' } }, { isDeleted: { '$eq': false } } ] } } } } }, serverInfo: { host: 'demo-cluster', port: 27017, version: '5.0.0' }, ok: 1, operationTime: Timestamp({ t: 1759915116, i: 1 }) }

다음은 Amazon DocumentDB 쿼리 실행 계획을 자세히 분석하여 각 구성 요소와 성능 특성을 분석한 것입니다.

전체 타이밍

executionTimeMillis는 계획 시간을 포함하여 쿼리에 걸린 총 시간을 나타냅니다.

planningTimeMillis는 쿼리에 소요된 총 계획 시간을 나타냅니다.

실행 단계

Amazon DocumentDB가 쿼리를 실행하는 데 사용하는 step-by-step 프로세스를 설명하여 다양한 작업을 통해 데이터가 흐르는 방식을 보여줍니다.

"executionStages": { "stage": "[STAGE_NAME]", "nReturned": "[NUMBER_OF_DOCS]", "executionTimeMillisEstimate": "[TIME]", "inputStage": { // Nested stages } }

쿼리 계획의 공통 단계

다음은 쿼리 계획의 일반적인 실행 단계입니다. 각 단계는 모든 단계에서 쿼리 성능을 평가하는 데 도움이 되도록 executionTimeMillisEstimate(실행 시간) 및 nReturned(문서 수) 지표를 반환합니다.

COLLSCAN(컬렉션 스캔)

  • 문서별로 전체 컬렉션 문서를 스캔합니다.

  • nReturned: 컬렉션에서 일치하는 모든 문서를 반환합니다.

  • 인덱스를 사용할 수 없는 경우 표시되는 비용이 많이 드는 작업일 수 있습니다.

IXSCAN(인덱스 스캔)

  • 인덱스를 사용하여 일치하는 문서를 찾습니다.

  • nReturned: 인덱스를 기반으로 문서만 일치

  • 효율적인 작업, COLLSCAN보다 선호

SORT

  • 지정된 필드를 기준으로 문서를 정렬합니다.

  • 쿼리의 정렬 속성이 인덱스의 일부가 아닌 경우이 단계는 명시적으로 표시됩니다.

  • nReturned: 입력 문서와 동일한 번호

  • 대규모 결과 집합에 대해 메모리 집약적입니다. 최적화하려면 인덱스에 정렬 필드 이름을 추가합니다.

LIMIT_SKIP

  • 반환되고 건너뛴 문서 수를 제어합니다.

  • nReturned: LIMIT 값으로 제한됨

  • 페이지 매김 또는 LIMIT 작업에 사용됩니다.

하위 스캔

  • 중첩 쿼리 작업 수행

  • nReturned: 하위 쿼리 결과에 따라 다름

  • 여러 단계가 있는 복잡한 쿼리에 사용

executionTimeMillisEstimate는 최적화를 위한 좋은 후보입니다.

참고

executionStats 파라미터는 현재 업데이트 및 삭제 명령을 지원하지 않습니다.

계획 실행 통계 설명의 docsExamined 이해

를 사용하여 쿼리를 실행하면 explain("executionStats") Amazon DocumentDB는 쿼리 결과를 생성하기 위해 스캔한 문서 수를 이해하는 데 도움이 되는 검사 지표를 제공합니다. 이러한 지표는 비효율적인 쿼리 계획을 식별하고 성능을 최적화하는 데 유용합니다.

참고

Amazon DocumentDB 8.0.0 이상에서만 사용할 수 있습니다.

필드

필드 설명 수준
totalDocsExamined 모든 실행 단계에서 검사한 총 문서 수입니다. 최상위 executionStats
docsExamined 특정 실행 단계에서 검사한 문서 수입니다. 단계 수준

docsExamined 필드는 다음 단계에 나타납니다.

단계 설명
콜스캔 컬렉션 스캔. 컬렉션의 모든 문서가 검사됩니다.
ISSCAN 인덱스 스캔. 인덱스 조건과 일치하는 문서만 검사됩니다.
FETCH 최적화 프로그램이 IXSCAN과 별도의 단계에서 문서를 검색하면 FETCH 단계는 docsExamined를 보고합니다. 인덱스 스캔 계획에서 하위 IXSCAN 단계는 docsExamined를 보고하지 않습니다. $lookup 계획에서 FETCH 단계와 하위 단계 모두 docsExamined를 보고할 수 있습니다.
참고

docsExamined는 문서에 액세스하지 않고 쿼리가 인덱스에서 완전히 충족되기 때문에 IXONLYSCAN 단계에 나타나지 않습니다.

계획 executionStats 출력 설명에 docsExamined 표시

다음 예제에서는 500,000개의 문서가 있는 컬렉션을 사용하고 다양한 쿼리 실행 단계에서가 어떻게 docsExamined 변경되는지 보여줍니다.

샘플 데이터 생성:

for (let i = 0; i < 500000; i++) { db.coll.insertOne({ number: i, arr: [i, [i+1]], value: "test", bool: i % 2 === 0 }); }

컬렉션 스캔(COLLSCAN)

인덱스가 없으면 Amazon DocumentDB는 전체 컬렉션 스캔을 수행합니다.

db.coll.find({ "number": { "$lt": 500 } }).explain("executionStats").executionStats

출력:

{ "executionSuccess" : true, "nReturned" : "500", "executionTimeMillis" : "282.055", "planningTimeMillis" : "0.085", "totalDocsExamined" : "500000", "executionStages" : { "stage" : "COLLSCAN", "nReturned" : "500", "executionTimeMillisEstimate" : "281.915", "docsExamined" : "500000", "filter" : { "number" : { "$lt" : 500 } } } }

500,000개의 모든 문서를 검사하여 500개의 결과를 반환했습니다. 숫자 필드에 인덱스를 생성하면 이를 개선할 수 있습니다.

인덱스 스캔(IXSCAN)

db.coll.createIndex({ number: 1 }); db.coll.find({ "number": { "$lt": 5000 } }).explain("executionStats").executionStats

출력:

{ "executionSuccess" : true, "nReturned" : "5000", "executionTimeMillis" : "3.047", "planningTimeMillis" : "0.296", "totalDocsExamined" : "5000", "executionStages" : { "stage" : "IXSCAN", "nReturned" : "5000", "executionTimeMillisEstimate" : "2.576", "indexName" : "number_1", "direction" : "forward", "docsExamined" : "5000", "indexCond" : { "$and" : [ { "number" : { "$lt" : 5000 } } ] } } }

인덱스를 사용하면 반환된 수와 일치하는 500,000개 문서 중 5,000개만 검사하고 가져왔습니다. 인덱스 조건은 쿼리와 일치하지 않는 495,000개의 문서를 필터링했습니다.

잔차 필터를 사용한 인덱스 스캔

db.coll.find({ "number": { "$lt": 5000 }, "arr": { "$gt": 4000 } }).explain("executionStats").executionStats

출력:

{ "executionSuccess" : true, "nReturned" : "999", "executionTimeMillis" : "15.367", "planningTimeMillis" : "0.115", "totalDocsExamined" : "5000", "executionStages" : { "stage" : "IXSCAN", "nReturned" : "999", "executionTimeMillisEstimate" : "15.170", "indexName" : "number_1", "direction" : "forward", "docsExamined" : "5000", "indexCond" : { "$and" : [ { "number" : { "$lt" : 5000 } } ] }, "filter" : { "arr" : { "$gt" : 4000 } } } }

인덱스 조건이 500,000개 중 5,000개의 문서와 일치하면의 잔차 필터가 결과를 999로 arr 줄였습니다. docsExamined 값 5,000은 인덱스 조건 이후이지만 잔차 필터가 적용되기 전에 검사된 모든 문서를 반영합니다.

IXSCAN을 사용하여 가져오기

db.coll.find({ "$or": [{ "number": { "$lt": 100000 } }, { "number": { "$gt": 400000 } }] }).explain("executionStats").executionStats

출력:

{ "executionSuccess" : true, "nReturned" : "199999", "executionTimeMillis" : "899.801", "planningTimeMillis" : "0.183", "totalDocsExamined" : "199999", "executionStages" : { "stage" : "FETCH", "nReturned" : "199999", "executionTimeMillisEstimate" : "894.141", "docsExamined" : "199999", "inputStage" : { "stage" : "IXOR", "nReturned" : "0", "executionTimeMillisEstimate" : "874.897", "inputStages" : [ { "stage" : "IXSCAN", "nReturned" : "100000", "executionTimeMillisEstimate" : "462.208", "indexName" : "number_1", "indexCond" : { "$and" : [ { "number" : { "$lt" : 100000 } } ] } }, { "stage" : "IXSCAN", "nReturned" : "99999", "executionTimeMillisEstimate" : "412.684", "indexName" : "number_1", "indexCond" : { "$and" : [ { "number" : { "$gt" : 400000 } } ] } } ] } } }

Amazon DocumentDB 옵티마이저가 가져오기 단계를 사용하여 문서를 검색하는 경우 FETCH 단계는를 보고합니다docsExamined. 하위 IXSCAN 단계는 문서에 직접 액세스하지 않고 인덱스 키만 스캔docsExamined하므로 보고하지 않습니다.

집계 조회가 포함된 FETCH

db.coll.explain("executionStats").aggregate([ { $match: { "number": { "$lt": 5 } } }, { $lookup: { from: "coll", pipeline: [{ $match: { "number": { "$lt": 3 } } }], as: "sub" } } ]).executionStats

출력:

{ "executionSuccess" : true, "nReturned" : "5", "executionTimeMillis" : "0.525", "planningTimeMillis" : "0.327", "totalDocsExamined" : "9", "executionStages" : { "stage" : "NESTED_LOOP_LOOKUP", "nReturned" : "5", "executionTimeMillisEstimate" : "0.163", "inputStages" : [ { "stage" : "IXSCAN", "nReturned" : "5", "executionTimeMillisEstimate" : "0.039", "indexName" : "number_1", "direction" : "forward", "docsExamined" : "5", "indexCond" : { "$and" : [ { "number" : { "$lt" : 5 } } ] } }, { "stage" : "FETCH", "nReturned" : "1", "executionTimeMillisEstimate" : "0.009", "docsExamined" : "1", "inputStage" : { "stage" : "AGGREGATE", "nReturned" : "1", "executionTimeMillisEstimate" : "0.044", "inputStage" : { "stage" : "IXSCAN", "nReturned" : "3", "executionTimeMillisEstimate" : "0.013", "indexName" : "number_1", "direction" : "forward", "docsExamined" : "3", "indexCond" : { "$and" : [ { "number" : { "$lt" : 3 } } ] } } } } ] } }

외부 IXSCAN은 일치하는 번호 < 5개 문서 5개를 검사했습니다. 내부 IXSCAN은 일치하는 번호 < 3인 문서 3개를 검사했고 FETCH 단계에서는 집계된 결과 1개를 검사했습니다. 9totalDocsExamined의는 모든 단계(5 + 3 + 1)의 합계입니다.