반응형
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(
자바스크립트 셸을 통한 맛보기기는 여기서 끝~!!!!!!!
반응형