Post List

2015년 8월 6일 목요일

MongoDB Study #10 Index : 생성, 관리

1. Index

RDBMS 제품에서 Index를 사용하는 이유는 원하는 Data들을 특정한 Data Structure 형태 (대표적으로 B*Tree) 에 저장해두고 빠른 검색을 하기 위해서 입니다.
MongoDB에서도 동일한 목적으로 Index 생성이 가능합니다.

기본적으로는 아래 4개의 명령어로 Index 생성 및 관리가 가능합니다.

db.collection.createIndex( ) : Index 생성
db.collection.dropIndex( ) : Index 삭제
db.collection.getIndexes( ) : Index 목록 확인
db.collection.reIndex( ) : Index 재구성

각각의 사용법에 대해서 아래에서 실습해 보도록 하겠습니다.

2. MongoDB Index의 특징

  - 대소문자를 엄격히 구분합니다.
  - Document를 Update 할때 해당 Key만 변경하지 않고 document 전체를 변경하는 경우 기존 Extent 공간 보다 커지면 더 큰 Extent로 Migration 될 수 있습니다. Collection 뿐만 아니라 Index에 대해서도 충분한 크기의 Extent 크기 설정이 중요합니다.
  - sort() 절과 limit()절을 적절히 사용하면 불필요한 검색을 피할 수 있기 때문에 성능 향상에 도움이 됩니다.

3. Index 생성 및 삭제 실습

db.emp.getIndexes()
[
        {
                "v" : 1,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "test.emp"
        }
]

db.emp.createIndex( { empno : 1 } , { unique : true } ); // unique 로 ASC ( 1 )
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}

db.emp.createIndex( { job : -1 } ); // DESC ( -1 )
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 2,
        "numIndexesAfter" : 3,
        "ok" : 1
}

db.emp.getIndexes()
[
        {
                "v" : 1,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "test.emp"
        },
        {
                "v" : 1,
                "unique" : true,
                "key" : {
                        "empno" : 1
                },
                "name" : "empno_1",
                "ns" : "test.emp"
        },
        {
                "v" : 1,
                "key" : {
                        "job" : -1
                },
                "name" : "job_-1",
                "ns" : "test.emp"
        }
]

db.system.indexes.find()
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.order" }
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.map_reduce_example" }
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.log" }
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.session_stat" }
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.emp" }
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.result_emp" }
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.system.js" }
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.bank" }
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.transfer" }
{ "v" : 1, "unique" : true, "key" : { "empno" : 1 }, "name" : "empno_1", "ns" : "test.emp" }
{ "v" : 1, "key" : { "job" : -1 }, "name" : "job_-1", "ns" : "test.emp" }

db.emp.dropIndex( { job : -1 } )
{ "nIndexesWas" : 3, "ok" : 1 }

db.runCommand( { dropIndexes : 'emp' , index : { empno : 1 } } )
{ "nIndexesWas" : 2, "ok" : 1 }

db.emp.getIndexes()
[
        {
                "v" : 1,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "test.emp"
        }
]

4. Index 재구성

RDBMS도 마찬가지겠지만, 기본적으로 MongoDB는 Balance*Tree 구조의 Index를 이용합니다.
Insert , Update, Remove 등의 DML 작업이 빈번하게 이루어 지면 B*Tree 구조의 불균형으로 검색 성능이 나빠질 수 있습니다.
Document 의 크기가 기존 Extent 공간 보다 큰 경우 더 큰 Extent 공간으로 Migration 될 수 있는데, 이것이 Index에 영향을 줘서 성능 저하 현상이 발생 할 수 있습니다.
이럴 경우 해결할 수 있는 유일한 방법은 Index의 재구성 (삭제 후 다시 생성) 입니다.

db.emp.createIndex( { comm : 1 } )
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}

db.emp.reIndex()
{
        "nIndexesWas" : 2,
        "nIndexes" : 2,
        "indexes" : [
                {
                        "key" : {
                                "_id" : 1
                        },
                        "name" : "_id_",
                        "ns" : "test.emp"
                },
                {
                        "key" : {
                                "comm" : 1
                        },
                        "name" : "comm_1",
                        "ns" : "test.emp"
                }
        ],
        "ok" : 1
}

db.runCommand( { reIndex : 'emp' } )
{
        "nIndexesWas" : 2,
        "nIndexes" : 2,
        "indexes" : [
                {
                        "key" : {
                                "_id" : 1
                        },
                        "name" : "_id_",
                        "ns" : "test.emp"
                },
                {
                        "key" : {
                                "comm" : 1
                        },
                        "name" : "comm_1",
                        "ns" : "test.emp"
                }
        ],
        "ok" : 1
}

댓글 없음:

댓글 쓰기