티스토리 뷰

2장 요약 -3


1. 인덱스 생성과 질의


1-1) 대용량 컬렉션 생성

- 인덱싱 테스트를 위해 간단히 대용량 컬렉션 생성

ex)20만개 도큐먼트를 가지는 컬렉션 생성 (시간이 꽤 걸린다.)

> use tutorial

switched to db tutorial

> for(i=0;i<200000;i++)db.numbers.save({num:i})

> db.numbers.count()
200000

- 쿼리 셀렉터에 큰값과 작은값을 위한 $gt, $lt 연산자를 지원
ex) 199995보다 큰값 가져오기
> db.numbers.find({num:{"$gt":199995}})
{ "_id" : ObjectId("582e87b124bc079e907d1b24"), "num" : 199996 }
{ "_id" : ObjectId("582e87b124bc079e907d1b25"), "num" : 199997 }
{ "_id" : ObjectId("582e87b124bc079e907d1b26"), "num" : 199998 }
{ "_id" : ObjectId("582e87b124bc079e907d1b27"), "num" : 199999 }

ex)20~25 사이의값 가져오기
> db.numbers.find({num:{"$gt":20,"$lt":25}})
{ "_id" : ObjectId("582e875b24bc079e907a0dfd"), "num" : 21 }
{ "_id" : ObjectId("582e875b24bc079e907a0dfe"), "num" : 22 }
{ "_id" : ObjectId("582e875b24bc079e907a0dff"), "num" : 23 }
{ "_id" : ObjectId("582e875b24bc079e907a0e00"), "num" : 24 }

1-2) 인덱스의 생성및 확인
- 관계형 데이터 베이스와 마찬가지로 쿼리가 사용한 인덱스를 찾아주는 explain() 함수제공.
- 쿼리뒤에 explain() 함수를 붙여 주면 됨.
ex)
> db.numbers.find({num:{"$gt":199995}}).explain();
{
        "queryPlanner" : {
                "plannerVersion" : 1,
                "namespace" : "tutorial.numbers",
                "indexFilterSet" : false,
                "parsedQuery" : {
                        "num" : {
                                "$gt" : 199995
                        }
                },
                "winningPlan" : {
                        "stage" : "COLLSCAN",
                        "filter" : {
                                "num" : {
                                        "$gt" : 199995
                                }
                        },
                        "direction" : "forward"
                },
                "rejectedPlans" : [ ]
        },
        "serverInfo" : {
                "host" : "parkui-MacBook-Pro.local",
                "port" : 27017,
                "version" : "3.2.10",
                "gitVersion" : "79d9b3ab5ce20f51c272b4411202710a082d0317"
        },
        "ok" : 1
}

- 책에서는 explain()만 사용해도 수행 시간이나, 스캔된 도큐먼트 갯수등 모든 정보가 나왔지만 현재 3.2버전에서는 위의 정보만 나온다
- 몽고디비 메뉴얼을 확인해본 결과 수행시간이나 상세 상태를 확인하기 위해선 explain()에 executionStats을 파라미터로 넘겨줘야 한다.
ex)
> db.numbers.find({num:{"$gt":199995}}).explain("executionStats");
{
        "queryPlanner" : {
                "plannerVersion" : 1,
                "namespace" : "tutorial.numbers",
                "indexFilterSet" : false,
                "parsedQuery" : {
                        "num" : {
                                "$gt" : 199995
                        }
                },
                "winningPlan" : {
                        "stage" : "COLLSCAN",
                        "filter" : {
                                "num" : {
                                        "$gt" : 199995
                                }
                        },
                        "direction" : "forward"
                },
                "rejectedPlans" : [ ]
        },
        "executionStats" : {
                "executionSuccess" : true,
                "nReturned" : 4,
                "executionTimeMillis" : 90,
                "totalKeysExamined" : 0,
                "totalDocsExamined" : 200000,
                "executionStages" : {
                        "stage" : "COLLSCAN",
                        "filter" : {
                                "num" : {
                                        "$gt" : 199995
                                }
                        },
                        "nReturned" : 4,
                        "executionTimeMillisEstimate" : 60,
                        "works" : 200002,
                        "advanced" : 4,
                        "needTime" : 199997,
                        "needYield" : 0,
                        "saveState" : 1562,
                        "restoreState" : 1562,
                        "isEOF" : 1,
                        "invalidates" : 0,
                        "direction" : "forward",
                        "docsExamined" : 200000
                }
        },
        "serverInfo" : {
                "host" : "parkui-MacBook-Pro.local",
                "port" : 27017,
                "version" : "3.2.10",
                "gitVersion" : "79d9b3ab5ce20f51c272b4411202710a082d0317"
        },
        "ok" : 1
}

- executionStats 결과의 상세 내용은 이곳 참조
- 위 결과를 확인해보면 단 4개의 결과를 가져오기 위해 COLLSCAN(stage)으로 200,000개의 도큐먼트를 모두 스캔(totalDocsExamined)하고 90ms(executionTimeMillis)가 걸린것을 확인할수 있다.

- 인덱스를 생성한후 결과를 비교해보자.
- 인덱스 생성은 ensureIndex()함수를 사용하고 파라미터로 인덱스를 생성할 키값과 정렬 방식을 JSON형태로 넘겨준다.
ex) numbers 컬렉션에 num키를 오름차순으로 인덱스 생성
> db.numbers.ensureIndex({num:1})
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
}

- 생성된 인덱스 확인은 getIndexes()함수 사용
ex)
> db.numbers.getIndexes()
[
        {
                "v" : 1,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "tutorial.numbers"
        },
        {
                "v" : 1,
                "key" : {
                        "num" : 1
                },
                "name" : "num_1",
                "ns" : "tutorial.numbers"
        }
]

- 결과를 보면 _id는 자동으로 인덱스가 생성되어 있고 방금 추가한 num에대해 인덱스가 생성된것을 볼수 있다.
- 이제 인덱스를 생성 했으니 다시한번 쿼리를 수행후 explain("executionStats")로 결과를 비교해보자.
ex)
> db.numbers.find({num:{"$gt":199995}}).explain("executionStats");
{
        "queryPlanner" : {
                "plannerVersion" : 1,
                "namespace" : "tutorial.numbers",
                "indexFilterSet" : false,
                "parsedQuery" : {
                        "num" : {
                                "$gt" : 199995
                        }
                },
                "winningPlan" : {
                        "stage" : "FETCH",
                        "inputStage" : {
                                "stage" : "IXSCAN",
                                "keyPattern" : {
                                        "num" : 1
                                },
                                "indexName" : "num_1",
                                "isMultiKey" : false,
                                "isUnique" : false,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 1,
                                "direction" : "forward",
                                "indexBounds" : {
                                        "num" : [
                                                "(199995.0, inf.0]"
                                        ]
                                }
                        }
                },
                "rejectedPlans" : [ ]
        },
        "executionStats" : {
                "executionSuccess" : true,
                "nReturned" : 4,
                "executionTimeMillis" : 3,
                "totalKeysExamined" : 4,
                "totalDocsExamined" : 4,
                "executionStages" : {
                        "stage" : "FETCH",
                        "nReturned" : 4,
                        "executionTimeMillisEstimate" : 0,
                        "works" : 5,
                        "advanced" : 4,
                        "needTime" : 0,
                        "needYield" : 0,
                        "saveState" : 0,
                        "restoreState" : 0,
                        "isEOF" : 1,
                        "invalidates" : 0,
                        "docsExamined" : 4,
                        "alreadyHasObj" : 0,
                        "inputStage" : {
                                "stage" : "IXSCAN",
                                "nReturned" : 4,
                                "executionTimeMillisEstimate" : 0,
                                "works" : 5,
                                "advanced" : 4,
                                "needTime" : 0,
                                "needYield" : 0,
                                "saveState" : 0,
                                "restoreState" : 0,
                                "isEOF" : 1,
                                "invalidates" : 0,
                                "keyPattern" : {
                                        "num" : 1
                                },
                                "indexName" : "num_1",
                                "isMultiKey" : false,
                                "isUnique" : false,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 1,
                                "direction" : "forward",
                                "indexBounds" : {
                                        "num" : [
                                                "(199995.0, inf.0]"
                                        ]
                                },
                                "keysExamined" : 4,
                                "dupsTested" : 0,
                                "dupsDropped" : 0,
                                "seenInvalidated" : 0
                        }
                }
        },
        "serverInfo" : {
                "host" : "parkui-MacBook-Pro.local",
                "port" : 27017,
                "version" : "3.2.10",
                "gitVersion" : "79d9b3ab5ce20f51c272b4411202710a082d0317"
        },
        "ok" : 1
}
- 결과가 뭔가 엄청나게 길어졌지만 위에서 봤던 stage, totalDocsExamined, executionTimeMillis를 확인해보면 COLLSCAN에서 IXSCAN으로
200000개에서 4개90ms에서 3ms로 인덱스를 생성한 효과가 확실히 다른것을 확인할 수 있다.
- 인덱스에 관련된부분은 나중에 다시 나온다.

2. 기본적인 관리

2-1) 데이터 베이스 정보 얻기
- 시스템상의 데이터베이스 정보는 show dbs로 확인한다.
ex)
> show dbs
local     0.000GB
tutorial  0.006GB

- 선택된 데이터 베이스의 컬렉션 정보는 show collections로 확인한다.
ex)
> show collections
numbers

- 데이터 베이스나 컬렉션에 대해서 좀더 상세한 정보는 stats()함수를 이용한다.
ex)db.numbers.stats()는 정보가 너무 많아 안적음
> db.stats()
{
        "db" : "tutorial",
        "collections" : 1,
        "objects" : 200000,
        "avgObjSize" : 35,
        "dataSize" : 7000000,
        "storageSize" : 2789376,
        "numExtents" : 0,
        "indexes" : 2,
        "indexSize" : 3862528,
        "ok" : 1
}

- 도움말이 필요한 경우 각 명령어 뒤에 help()함수를 사용한다.
ex)
> db.help()
DB methods:
        db.adminCommand(nameOrDocument) - switches to 'admin' db, and runs command [ just calls db.runCommand(...) ]
        db.auth(username, password)
        db.cloneDatabase(fromhost)
        ,,,,,,,,,,,,,,,,,,

- 탭키를 누르거나 더블탭을 사용하면 자동완성 or 해당 단어가 포함된 함수 리스트를 보여준다.
ex)
> db.numbers.find
db.numbers.find(               db.numbers.findOne(            db.numbers.findOneAndReplace(
db.numbers.findAndModify(      db.numbers.findOneAndDelete(   db.numbers.findOneAndUpdate(


자바스크립트 셸을 통한 맛보기기는 여기서 끝~!!!!!!!


댓글