티스토리 뷰

DB/MongoDB

[MongoDB] 인덱싱2

snail voyager 2023. 4. 18. 22:25
728x90
반응형

5.2 explain 출력

  • 쿼리에 대한 많은 정보를 제공, 느린 쿼리를 위한 중요한 진단 도구
  • 어떤 인덱스가 어떻게 사용되는지 알 수 있음
  • 쿼리 마지막에 explain 호출 추가
  • 쿼리가 "COLLSCAN"을 사용하면 인덱스를 사용하지 않음
  • "needYields" : 쓰기 요청을 처리하도록 쿼리가 양보(일시정지)한 횟수
    대기 중인 쓰기가 있다면 쿼리는 일시적으로 락을 해제하고 쓰기 처리
  • "indexBounds" : 인덱스가 어떻게 사용됐는지 설명하며 탐색한 인덱스의 범위를 제공
  • {"username": 1, "age":1}, {"age":1, "username":1} 인덱스 존재 시
    쿼리마다 사용 인덱스 상이
> db.users.find({"age":{&gt:10}, "username":"user2134"}).explain()	//{"username":1,"age":1} 인덱스 사용

> db.users.find({"age":14, "username":/.*/}).explain()	//{"age":1, "username":1} 인덱스 사용
  • 쿼리에 사용하려 했던 인덱스와 다른 인덱스를 사용하려면 hint 사용
    힌트가 적용된 쿼리가 배포되기 전에 explain 실행해야해서 비효율
> db.users.find({"age" : 14, "username" : /.*/}).hint({"username":1, "age":1})

 

5.3 인덱스를 생성하지 않는 경우

  • 인덱스는 데이터의 일부를 조회할 때 가장 효율적
  • 인덱스가 없는게 더 빠를수도 있음
  • 인덱스는 컬렉션에서 가져와야 하는 부분이 많을수록 비효율
  • 하나의 인덱스를 사용하려면 두 번의 조회
    인덱스 항목을 조회, 도큐먼트를 가리키는 인덱스의 포인터를 따라감
인덱스가 적합한 경우 컬렉션 스캔이 적합한 경우
큰 컬렉션 작은 컬렉션
큰 도큐먼트 작은 도큐먼트
선택적 쿼리 비선택적 쿼리

 

5.4 인덱스 종류

5.4.1 고유 인덱스

  • 각 값이 인덱스에 최대 한번 나타나도록 보장
  • 중복 키 예외를 발생시키면 매우 비효율적
  • 가끔씩 발생하는 중복에 고유 제약 조건 사용
  • 고유 인덱스인 "_id" 의 인덱스는 컬렉션을 생성하면 항상 자동 생성. 삭제 불가
  • 도큐먼트에 키가 존재하지 않으면 인덱스는 null 로 저장
    고유 인덱스에서 필드가 없는 도큐먼트를 2개 삽입 시도하면 실패
  • 8Kbyte보다 긴 키에는 고유 인덱스 제약 조건 적용 불가
> db.users.createIndex({"firstname":1},
	{"unique":true, "partialFilterExpression":{"firstname":{$exists:true}}})

복합 고유 인덱스

  • 인덱스 항목의 모든 키에 걸친 값의 조합은 인덱스에서 최대 한번만 나타남
// {"username":1, "age":1} index
> db.users.insert({"username" : "bob"})
> db.users.insert({"username" : "bob", "age" : 23})
> db.users.insert({"username" : "fred", "age" : 23})

중복 제거하기

  • 기존 컬렉션에 고유 인덱스를 구축할 때 중복된 값이 있으면 실패

5.4.2 부분 인덱스

  • 키가 존재할 때만 고유 인덱스가 적용할 경우 사용
  • 고유하지 않은 부분 인덱스를 만드려면 "unique" 옵션 제외
  • 쿼리는 부분 인덱스 사용 여부에 따라 다른 결과 반환
  • 필드가 없는 도큐먼트가 필요할 때는 hint 사용
> db.users.ensureIndex({"email":1}, 
	{"unique":true, "partialFilterExpression": {"email": {$exists:true} }})	//email 선택항목, 입력할 경우 unique
    
> db.foo.find()
{"_id":0}	//"x" 없음
{"_id":1, "x":1}
{"_id":2, "x":2}
{"_id":3, "x":3}

> db.foo.find({"x": {"$ne":2}})
{"_id":0}
{"_id":1, "x":1}
{"_id":3, "x":3}

> db.foo.ensureIndex({"x":1}, "partialFilterExpression": {"x": {$exists:true} }}) //부분 인덱스 생성
> db.foo.find({"x": {"$ne":2}})
// "_id":0 도큐먼트는 인덱스에 포함되지 않아 반환 X
{"_id":1, "x":1}
{"_id":3, "x":3}

 

5.5 인덱스 관리

  • 인덱스는 컬렉션당 한번만 들어야함. 재생성하면 무의미
  • 인덱스 정보는 system.indexes 컬렉션에 저장
  • 특정 컬렉션의 모든 인덱스 정보 확인 db.컬렉션명.getIndexes()
  • "key"는 hint에 사용하거나 인덱스가 명시돼야 하는 위치에 사용
  • "name" 은 dropIndexes 같은 관리적인 인덱스 작업에서 식별자로 사용
  • "v" 는 내부적으로 인덱스 versioning에 사용

5.5.1 인덱스 식별

  • createIndex 옵션으로 이름 이정
> db.soup.createIndex({"a":1, "b":1...}, {"name":"IndexName"})

5.5.2 인덱스 변경

  • dropIndex 명령으로 불필요한 인덱스 제거
  • 인덱스를 최대한 빨리 구축하기 위해, 완료될 때까지 모든 읽기와 쓰기 중단
  • 읽기, 쓰기 어느정도 응답하려면 인덱스 구축 시 "background"  옵션 사용
  • 도큐먼트가 있는 상태에서 인덱스 생성하는게 더 빠름
> db.people.dropIndex({"x_1_y_1"})
728x90
반응형

'DB > MongoDB' 카테고리의 다른 글

[MongoDB] 집계 프레임워크  (0) 2023.05.10
[MongoDB] 공간 정보 인덱스  (0) 2023.04.26
[MongoDB] 인덱싱  (0) 2023.03.22
[MongoDB] 쿼리  (0) 2023.03.15
[MongoDB] 도큐먼트 생성, 갱신, 삭제  (0) 2023.03.06
반응형
300x250