다음을 통해 공유


Azure Cosmos DB for MongoDB vCore의 인덱싱 모범 사례

적용 대상: MongoDB vCore

쿼리 가능한 필드에는 항상 인덱스가 생성됩니다.

조건자 및 집계를 기준으로 하는 읽기 작업은 해당 필터에 대한 인덱스를 참조합니다. 인덱스가 없는 경우 데이터베이스 엔진은 문서 검색을 수행하여 일치하는 문서를 검색합니다. 검색은 항상 비용이 많이 들고 컬렉션의 데이터 볼륨이 증가함에 따라 점점 더 많은 비용이 듭니다. 최적의 쿼리 성능을 위해 항상 모든 쿼리 가능한 필드에 대해 인덱스를 만들어야 합니다.

기본적으로 불필요한 인덱스 및 모든 필드 인덱싱 방지

쿼리 가능한 필드에 대해서만 인덱스를 만들어야 합니다. 와일드카드 인덱싱은 문서 구조의 모든 필드가 쿼리 필터의 일부가 될 수 있는 쿼리 패턴을 예측할 수 없는 경우에만 사용해야 합니다.

Azure Cosmos DB for MongoDB vCore는 기본적으로 _id 필드만 인덱싱합니다. 기타 모든 필드는 기본적으로 인덱싱되지 않습니다. 너무 많은 필드를 인덱싱하게 되어 쓰기에 영향을 미치는 상황을 최소화하면서 쿼리 성능을 최대화하려면 인덱싱할 필드를 미리 계획해야 합니다.

새 문서가 처음으로 삽입되거나 기존 문서가 업데이트되거나 삭제되면 인덱스의 지정된 각 필드도 업데이트됩니다. 인덱싱 정책에 많은 수의 필드(또는 문서의 모든 필드)가 포함된 경우 서버에서 해당 인덱스를 업데이트하는 데 더 많은 리소스가 사용됩니다. 대규모로 실행하는 경우 쿼리 조건자에서 사용되지 않는 나머지 모든 필드를 인덱스에서 제외하면서 쿼리 가능한 필드만 인덱싱해야 합니다.

데이터 수집 전에 필요한 인덱스 만들기

최적의 성능을 위해 데이터를 로드하기 전에 인덱스를 미리 만들어야 합니다. 모든 문서 쓰기, 업데이트 및 삭제 작업이 진행되면 해당 인덱스가 동기적으로 업데이트됩니다. 데이터를 수집한 후 인덱스가 만들어지면 기록 데이터를 인덱싱하는 데 더 많은 서버 리소스가 사용됩니다. 기록 데이터의 크기에 따라 이 작업은 시간이 오래 걸리며 안정적인 상태 읽기 및 쓰기 성능에 영향을 줍니다.

참고 항목

읽기 패턴이 변경되고 인덱스를 추가해야 하는 시나리오의 경우 지원 티켓을 통해 수행할 수 있는 백그라운드 인덱싱을 사용하도록 설정해야 합니다.

기록 데이터에 대해 만든 여러 인덱스의 경우 각 필드에 대해 nonblocking createIndex 명령을 실행합니다.

특히 애플리케이션 요구 사항이 진화함에 따라 모든 쿼리 패턴을 미리 계획할 수 있는 것은 아닙니다. 애플리케이션 요구 사항을 변경하려면 많은 양의 기록 데이터가 있는 클러스터의 인덱스에 필드를 추가할 수 밖에 없습니다.

이러한 시나리오에서 각 createIndex 명령은 서버의 응답을 기다리지 않고 비동기적으로 실행해야 합니다.

참고 항목

기본적으로 Azure Cosmos DB for MongoDB vCore는 기록 데이터에 대해 인덱스가 완전히 빌드된 후에만 createIndex 작업에 응답합니다. 클러스터의 크기와 수집된 데이터의 볼륨에 따라 시간이 걸릴 수 있으며 서버가 createIndex 명령에 응답하지 않는 것처럼 보일 수 있습니다.

Mongo Shell을 통해 createIndex 명령을 실행 중인 경우 Ctrl+C로 명령을 중단하여 응답 대기를 중지하고 다음 작업 모음을 실행합니다.

참고 항목

createIndex 명령이 실행된 후 Ctrl+C로 중단해도 서버에서 인덱스 빌드 작업이 종료되지는 않습니다. 서버가 기존 문서에 대해 인덱스 빌드를 비동기적으로 계속하는 동안 셸이 서버의 응답을 더 이상 기다리지 않게 됩니다.

여러 필드에 조건자가 있는 쿼리에 대한 복합 인덱스 만들기

복합 인덱스는 다음 시나리오에서 사용해야 합니다.

  • 여러 필드에 대한 필터가 있는 쿼리
  • 여러 필드에 필터가 있고 하나 이상의 필드가 오름차순 또는 내림차순으로 정렬된 쿼리

'cosmicworks' 데이터베이스 및 'employee' 컬렉션 내에서 다음 문서를 고려합니다.

{
    "firstName": "Steve",
    "lastName": "Smith",
    "companyName": "Microsoft",
    "division": "Azure",
    "subDivision": "Data & AI",
    "timeInOrgInYears": 7
}

조직에서 성이 'Smith'이고 5년 이상 근무한 모든 직원을 찾으려면 다음 쿼리를 사용합니다.

db.employee.find({"lastName": "Smith", "timeInOrgInYears": {"$gt": 5}})

'lastName' 및 'timeInOrgInYears'의 복합 인덱스는 다음 쿼리를 최적화합니다.

use cosmicworks;
db.employee.createIndex({"lastName" : 1, "timeInOrgInYears" : 1})

createIndex 작업의 상태 추적

인덱스가 추가되고 기록 데이터를 인덱싱해야 하는 경우 db.currentOp()를 사용하여 인덱스 빌드 작업의 진행률을 추적할 수 있습니다.

'cosmicworks' 데이터베이스의 인덱싱 진행률을 추적하려면 다음 샘플을 사용합니다.

use cosmicworks;
db.currentOp()

createIndex 작업이 진행 중인 경우 응답은 다음과 같습니다.

{
  "inprog": [
    {
      "shard": "defaultShard",
      "active": true,
      "type": "op",
      "opid": "30000451493:1719209762286363",
      "op_prefix": 30000451493,
      "currentOpTime": "2024-06-24T06:16:02.000Z",
      "secs_running": 0,
      "command": { "aggregate": "" },
      "op": "command",
      "waitingForLock": false
    },
    {
      "shard": "defaultShard",
      "active": true,
      "type": "op",
      "opid": "30000451876:1719209638351743",
      "op_prefix": 30000451876,
      "currentOpTime": "2024-06-24T06:13:58.000Z",
      "secs_running": 124,
      "command": { "createIndexes": "" },
      "op": "workerCommand",
      "waitingForLock": false,
      "progress": {},
      "msg": ""
    }
  ],
  "ok": 1
}

기본적으로 큰 인덱스 키 사용

문서에 많은 문자가 있는 키가 없거나 문서에 여러 수준의 중첩이 포함되어 있지 않더라도 큰 인덱스 키를 지정하면 이러한 시나리오가 적용됩니다.

'cosmicworks' 데이터베이스의 'large_index_coll' 컬렉션에서 큰 인덱스 키를 사용하도록 설정하려면 다음 샘플을 사용합니다.

use cosmicworks;
db.runCommand(
{
 "createIndexes": "large_index_coll",
 "indexes": [
    {
        "key": { "ikey": 1 },
        "name": "ikey_1",
        "enableLargeIndexKeys": true
    }
    ]
})

차단 옵션을 사용하여 새 쓰기 작업보다 인덱스 빌드에 우선 순위 지정

데이터를 로드하기 전에 인덱스를 만들어야 하는 시나리오의 경우 차단 옵션을 사용해서 인덱스 빌드가 완료될 때까지 들어오는 쓰기를 차단해야 합니다.

{ "blocking": true } 설정 기능은 데이터 쓰기가 시작되기 전에 빈 컬렉션에 인덱스를 만드는 마이그레이션 유틸리티에서 특히 유용합니다.

'cosmicworks' 데이터베이스의 'employee' 컬렉션에서 인덱스 만들기에 대한 차단 옵션의 예를 생각해 보세요.

use cosmicworks;
db.runCommand({
  createIndexes: "employee",
  indexes: [{"key":{"name":1}, "name":"name_1"}],
  blocking: true
})

텍스트 기반 데이터를 효율적으로 검색하고 쿼리할 수 있는 텍스트 인덱싱을 확인합니다.

다음 단계