Index
- 디비의 검색을 빠르게 하기 위하여 미리 데이터의 순서를 정리해두는 과정
- MongoDB는 고정된 스키마는 없지만 원하는 데이터 필드를 인덱스로 지정하여 검색결과를 빠르게 하는것이 가능
- NOSQL 에서도 index를 잘 설계해야 최대의 효율이 가능
- MongoDB를 효율적으로 사용하고 하드웨어의 성능을 최대로 끌어내려면 index 종류와 사용 방법에 대한 이해 필요
- MongoDB는 B트리 구조로 index를 구현
- 고유 index, 최소 index, 다중 키 index 지원
- 복합 index, 단일 index 지원
Index 개념
- 도큐먼트를 쿼리해오기 위한 작업량을 줄임
- 적당한 인덱스가 없으면 질의 조건을 만족할 때까지 모든 도큐면트를 순차적으로 스캔
- 한 쿼리당 하나의 index만 유효
- 두 개의 index가 필요하다면, 복합 index 사용
- a,b 필드로 구성된 복합 index를 가지고 있다면 a에 대해 단일 index는 제거 가능
- 복합 index에서 키의 순서 매우 중요
- _id는 기본적으로 생성되는 index로 도큐먼트를 가르키는 유일한 키값으로 사용
도큐먼트에 빠르게 접근하기 위해 각 _id는 index로 관리됨
Index 효율
- 쿼리 성능 향상을 위해 무한히 index를 추가하는 것은 불가능
- 모든 index에는 결국 유지비가 소요됨
- 어떤 데이터가 도큐먼트에 추가되거나 수정될 때 마다 그 컬렉션에 대해 생성된 index도 그 새로운 도큐먼트를 포함시키도록 수정되어야 함
- 최악의 경우에는 결국 데이터를 다시 정렬해야 하는 상황 발생
- index는 읽기 위주의 어플리케이션에서 유용
- 읽기보다 쓰기 작업이 많다면 어느정도 index를 포기하거나 index를 위한 컬렉션을 따로 운영해야 함
- MongoDB는 기동 시, 모든 데이터 파일을 메모리에 매핑함
- 모든 도큐먼트, 컬렉션, 인덱스를 포함하는 데이터 파일이 페이지 라고 부르는 4kb 정도의 청크 단위로 운영체제에 의해 램에 적재됨
- 램의 모든 데이터를 수용만 할 수있다면 디스크 액세스 횟수 최소화가 가능
- 모든 데이터를 수용하지 못하면 페이지 폴트가 자주 발생하게 되고 운영체제가 디스크를 빈번하게 액세스하게 됨으로 읽기/쓰기 연산 지연 발생
- 스래싱(thrashing) : 모든 데이터를 디스크에서 액세스 해야하는 경우 굉장한 성능저하를 초래함
- 최소한의 인덱스가 메모리에 위치할 수 있도록 최소화될 필요가 있음
- 복합 인덱스는 더 많은 공간을 필요로함을 고려해야 함
B트리
- MongoDB는 내부적으로 B-Tree 알고리즘을 이용하여 인덱스를 구성
- B-Tree는 1970년대 후반부터 데이터베이스의 레코드와 인덱스로 활발하게 사용되고 있음
- 트리구조와 유사한 데이터 구조
- 트리에서 각 노드는 여러 개의 키를 갖는 것이 가능
- MongoDB에서 사용하는 B-Tree는 새 노드에 대해 8,192 바이트를 할당함
(= 각 노드가 수백 개의 키를 가질 수 있음을 의미) - 인덱스의 평균 크기에 따라 달라질 수도 있지만,
보통 키의 평균적인 크기는 30바이트 안팎
B트리의 데이터베이스 인덱스에 적합한 두 가지 특징
- 정확한 일치, 범위 조건, 정렬, 프리픽스 일치 등 다양한 쿼리를 용이하게 처리하도록 도와줌
- 키가 추가되거나 삭제되더라도 밸런스 유지
MongoDB Index
인덱스 확인
- db.컬렉션.getIndexes()
인덱스 생성
- db.컬렉션.createIndex( {"name":1} ) - 오름차순 1, 내림차순 -1
인덱스 생성 - 백그라운드 옵션
- 컬렉션 내 데이터가 많을 경우 인덱스 생성으로 인한 비용을 줄이기 위해 사용
- db.컬렉션.createIndex( {"name":1}, {background:true} )
인덱스 생성 - 고유 인덱스
- db.컬렉션.createIndex( {"name":1}, {unique:true} )
- unique 속성을 지정하여 중복 데이터가 저장되지 못하도록 하면, 데이터 저장과 검색속도를 늘리는데 도움이 됨
인덱스 삭제 - 특정 필드
- db.컬렉션.dropIndex( {"name":1});
인덱스 삭제 - 모든 인덱스
- db.컬렉션.dropIndexs();
인덱스 유무에 따른 검색 속도 비교
1백만 건의 문서를 가지는 컬렉션 생성
for (i=0; i<1000000; i++) {
db.users.insert (
{
"i" : i,
"username" : "user" + i,
"age" : Math.floor(Math.random()*120),
"created" : new Date()
}
);
}
특정 사용자 정보를 가진 문서를 찾기
- db.users.find({username:"user101"}).explain()
- 인덱스가 존재하지 않으므로 풀스캔 / 721 millis
인덱스 생성
- db.users.createIndex("username":1})
- 인덱스가 존재 / 3millis
인덱스 사용 시 주의점
- 인덱스를 사용하면 쿼리 수행 시간이 단축됨
- 모든 쓰기 ( 읽기, 갱신, 삭제 ) 작업은 인덱스 때문에 더 오래 걸린다.
- 데이터가 변경될 때 마다 문서 자체는 물론이고 몽고디비에서 모든 인덱스를 갱신한다.
- 몽고디비는 컬렉션당 최대 64개의 인덱스를 가지도록 제한된다.
- 일반적으로 컬렉션에 2-3개 이상의 인덱스를 가지지 않는 것이 좋다.
- 몽고디비 인덱스는 전형적인 관계형 데이터베이스의 인덱스와 거의 흡사하게 작동된다.
- 새로운 인덱스를 구축하려면 오랜 시간이 걸리고 자원을 많이 먹는다.
- 몽고디비는 인덱스 구축이 완료될 때 까지 데이터베이스의 모든 읽기와 쓰기를 중단하며 구축한다.
- background 옵션은 사용하여 인덱스를 구축하면 다른 작업이 가능하기는 하지만 효율성이 떨어지고 포그라운드 인덱싱보다 훨씬 느리다.
'DataBase > MongoDB' 카테고리의 다른 글
MongoDB를 이용한 복제 방법 살펴보기 (0) | 2021.10.12 |
---|---|
MongoDB의 샤딩에 대해 알아보기 (0) | 2021.10.06 |
MongoDB 쉘을 이용하여 저장된 데이터를 수정하거나 삭제하기 (0) | 2021.09.24 |
MongoDB 쉘을 이용하여 데이터 저장하고 조회하기 (0) | 2021.09.23 |
MongoDB와 Node.js의 동작 방식 (0) | 2021.08.27 |