データベース例
データベースはこの前 作ったデータベースにデータを足して作ってみましょう。
適当に1000万レコードほど追加しました。
$ mongo d1
(snip)
> db.t1.find().count()
10110005
そこでもう一回DEXを実行してみますが、まだクエリを実行していないので当然何も出ません。
$ dex -f /var/log/mongodb/mongodb.log mongodb://localhost
{
'runStats': {
'linesRecommended': 0,
'linesProcessed': 1,
'linesPassed': 149
},
'results': []
}
では、Indexのきいていないクエリを打ってみましょう
どれも10秒以上かかります。重い。
$ mongo d1
# クエリ1つ目
> db.t1.find( { "nosql" : "mongodb"} )
{ "_id" : ObjectId("567365cf760961552b000001"), "created_at" : ISODate("2015-12-16T13:04:10Z"), "name" : "kuwa_tw", "nosql" : "mongodb", "price" : 10 }
# クエリ2つ目
> db.t1.find( { "name" : "saeoshi"} )
{ "_id" : ObjectId("567365cf760961552b000005"), "created_at" : ISODate("2015-12-16T13:04:38Z"), "name" : "saeoshi", "nosql" : "voldemote", "price" : 2000 }
# クエリ3つ目
> db.t1.find( { "price" : { $gt: 9000 } } )
(いっぱい出たのでsnip)
>
# クエリ4つ目:複合条件
> db.t1.find( { "name" : "kakerukaeru" , "price" : { $gt: 10 } } )
>
そうしたらそこでもう一回DEXを実行してみましょう。
そうすると、重かったクエリをピックアップして、どのようなインデックスをはればいいのかRecommendしてくれます。これは素晴らし。
$ dex -f /var/log/mongodb/mongodb.log mongodb://localhost
{
'runStats': {
'linesRecommended': 7,
'linesProcessed': 7,
'linesPassed': 201
},
'results': [
{
'queryMask': '{"$query":{"name":"<val>","price":{"$gt":"<val>"}}}',
'namespace': 'd1.t1',
'recommendation': {
'index': '{"name": 1, "price": 1}',
'namespace': 'd1.t1',
'shellCommand': 'db["t1"].ensureIndex({"name": 1, "price": 1}, {"background": true})'
},
'details': {
'count': 3,
'totalTimeMillis': 52289,
'avgTimeMillis': 17429
}
},
{
'queryMask': '{"$query":{"name":"<val>"}}',
'namespace': 'd1.t1',
'recommendation': {
'index': '{"name": 1}',
'namespace': 'd1.t1',
'shellCommand': 'db["t1"].ensureIndex({"name": 1}, {"background": true})'
},
'details': {
'count': 2,
'totalTimeMillis': 35758,
'avgTimeMillis': 17879
}
},
{
'queryMask': '{"$query":{"nosql":"<val>"}}',
'namespace': 'd1.t1',
'recommendation': {
'index': '{"nosql": 1}',
'namespace': 'd1.t1',
'shellCommand': 'db["t1"].ensureIndex({"nosql": 1}, {"background": true})'
},
'details': {
'count': 1,
'totalTimeMillis': 17983,
'avgTimeMillis': 17983
}
},
{
'queryMask': '{"$query":{"price":{"$gt":"<val>"}}}',
'namespace': 'd1.t1',
'recommendation': {
'index': '{"price": 1}',
'namespace': 'd1.t1',
'shellCommand': 'db["t1"].ensureIndex({"price": 1}, {"background": true})'
},
'details': {
'count': 1,
'totalTimeMillis': 17488,
'avgTimeMillis': 17488
}
}
]
}
ついでにexplainもしてみましょう。
> db.t1.find( { "name" : "kakerukaeru" , "price" : { $gt: 10 } } ).explain()
{
"cursor" : "BasicCursor",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 10110005,
"nscanned" : 10110005,
"nscannedObjectsAllPlans" : 10110005,
"nscannedAllPlans" : 10110005,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 18,
"nChunkSkips" : 0,
"millis" : 17893,
"indexBounds" : {
},
"server" : "ip-172-31-20-34:27017"
}
当たり前ながらIndexが無いので当然BasicCursorです。
ではRecommendにしたがってIndexを貼ってみましょう
> db["t1"].ensureIndex({"name": 1, "price": 1}, {"background": true})
> db["t1"].getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"ns" : "d1.t1",
"name" : "_id_"
},
{
"v" : 1,
"key" : {
"name" : 1,
"price" : 1
},
"ns" : "d1.t1",
"name" : "name_1_price_1",
"background" : true
}
]
はいIndexれましたね。
ではもう一回explainしてみましょ。
爆速!!!
> db.t1.find( { "name" : "kakerukaeru" , "price" : { $gt: 10 } } ).explain()
{
"cursor" : "BtreeCursor name_1_price_1",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 0,
"nscannedObjectsAllPlans" : 0,
"nscannedAllPlans" : 0,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"name" : [
[
"kakerukaeru",
"kakerukaeru"
]
],
"price" : [
[
10,
1.7976931348623157e+308
]
]
},
"server" : "ip-172-31-20-34:27017"
}
BtreeCursorになってIndex[name_1_price_1]が使われているのがわかると思います。
というわけで、Indexはメモリを食うので一概に貼りまくったらええというわけではないんですが、定期的にDEXを流すことでIndexが使われていないクエリが流れていないかを確認することができます。
簡単に使えるので使っていくと幸せになりますよ。
MongoDB使ってる時点で幸せなのかよくわかりませんがね。。。(怪談的な終わり方)
MongoDB in Action
- 作者: Kyle Banker,Peter Bakkum,Shaun Verch,Douglas Garrett,Tim Hawkins
- 出版社/メーカー: Manning Pubns Co
- 発売日: 2016/04/15
- メディア: ペーパーバック
- この商品を含むブログを見る