MongoDBクエリー最適化分析
18299 ワード
要約:
MySQLでは、スロー・クエリー・ログがクエリーの最適化の根拠としてよく使われていますが、MongoDBでは似たような機能がありますか?答えは肯定的です.それはProfiling機能をオンにすることです.このツールは、実行されたインスタンスでMongoDBに関する書き込み操作、カーソル、データベースコマンドなどを収集し、データベース・レベルでツールを開くことも、インスタンス・レベルで開くこともできます.ツールは、収集されたすべてをsystem.profileセットに書き込みます.このセットはcapped collectionです.詳細については、http://docs.mongodb.org/manual/tutorial/manage-the-database-profiler/を参照してください.
使用方法:
1:Profilingレベルの説明
2:プロファイルと設定をオンにする
3:プロファイルを閉じる
4:スロー・クエリー・ログのサイズ変更
注意:Secondaryのシステムを変更します.Profileのサイズは、Secondaryを停止し、独立して実行してから、上記の手順を実行する必要があります.完了したら、レプリカセットへの追加を再起動します.
遅いクエリー(system.profile)の説明:
以下の例で説明するが、詳細については、http://docs.mongodb.org/manual/reference/database-profiler/を参照してください.
1:パラメータの意味
上には次のものがあります.
getmoreはgetmore操作であり、getmoreは通常、結果セットの比較的大きなクエリで発生し、最初のqueryは結果の一部を返し、後続の結果はgetmoreによって取得されます.
nscanned(スキャンされた記録数)がnreturned(結果を返す記録数)よりはるかに大きい場合は、インデックスによる記録位置決めの最適化を考慮する.responseLengthが大きすぎると、返される結果セットが大きすぎることを示します.この場合、必要なフィールドだけが必要かどうかを見ます.
2:日常的に使用するクエリー
まとめ:
Profiling機能は効率に影響を与えるに違いないが、systemを使用しているため、あまり深刻ではない.記録するprofileはcapped collectionというcollectionの操作にはいくつかの制限と特徴がありますが、効率が高いので、使用時にこの機能を開くことができ、ずっと開く必要はありません.
MySQLでは、スロー・クエリー・ログがクエリーの最適化の根拠としてよく使われていますが、MongoDBでは似たような機能がありますか?答えは肯定的です.それはProfiling機能をオンにすることです.このツールは、実行されたインスタンスでMongoDBに関する書き込み操作、カーソル、データベースコマンドなどを収集し、データベース・レベルでツールを開くことも、インスタンス・レベルで開くこともできます.ツールは、収集されたすべてをsystem.profileセットに書き込みます.このセットはcapped collectionです.詳細については、http://docs.mongodb.org/manual/tutorial/manage-the-database-profiler/を参照してください.
使用方法:
1:Profilingレベルの説明
0: , 。
1: , 100 。
2:
2:プロファイルと設定をオンにする
1: mongo shell:
# :
drug:PRIMARY> db.getProfilingStatus()
{ "was" : 1, "slowms" : 100 }
#
drug:PRIMARY> db.getProfilingLevel()
1
#
drug:PRIMARY> db.setProfilingLevel(2)
{ "was" : 1, "slowms" : 100, "ok" : 1 }
#
drug:PRIMARY> db.setProfilingLevel(1,200)
{ "was" : 2, "slowms" : 100, "ok" : 1 }
test , , , :
2: mongo shell:
mongod --profile=1 --slowms=15 2 :
profile = 1
slowms = 300
3:プロファイルを閉じる
#
drug:PRIMARY> db.setProfilingLevel(0)
{ "was" : 1, "slowms" : 200, "ok" : 1 }
4:スロー・クエリー・ログのサイズ変更
# Profiling
drug:PRIMARY> db.setProfilingLevel(0)
{ "was" : 0, "slowms" : 200, "ok" : 1 }
# system.profile
drug:PRIMARY> db.system.profile.drop() true
# system.profile
drug:PRIMARY> db.createCollection( "system.profile", { capped: true, size:4000000 } )
{ "ok" : 1 }
# Profiling
drug:PRIMARY> db.setProfilingLevel(1)
{ "was" : 0, "slowms" : 200, "ok" : 1 }
注意:Secondaryのシステムを変更します.Profileのサイズは、Secondaryを停止し、独立して実行してから、上記の手順を実行する必要があります.完了したら、レプリカセットへの追加を再起動します.
遅いクエリー(system.profile)の説明:
以下の例で説明するが、詳細については、http://docs.mongodb.org/manual/reference/database-profiler/を参照してください.
1:パラメータの意味
drug:PRIMARY> db.system.profile.find().pretty()
{
"op" : "query", # , insert、query、update、remove、getmore、command
"ns" : "mc.user", #
"query" : { #
"mp_id" : 5,
"is_fans" : 1,
"latestTime" : {
"$ne" : 0
},
"latestMsgId" : {
"$gt" : 0
},
"$where" : "new Date(this.latestNormalTime)>new Date(this.replyTime)"
},
"cursorid" : NumberLong("1475423943124458998"),
"ntoreturn" : 0, # 。 ,profile ( ), ntoreturn 1。limit(5) , ntoreturn 5。 ntoreturn 0, , find() 。
"ntoskip" : 0, #skip()
"nscanned" : 304, #
"keyUpdates" : 0, # , , key, key B-
"numYield" : 0, #
"lockStats" : { # ,R: ;W: ;r: ;w:
"timeLockedMicros" : { #
"r" : NumberLong(19467),
"w" : NumberLong(0)
},
"timeAcquiringMicros" : { #
"r" : NumberLong(7),
"w" : NumberLong(9)
}
},
"nreturned" : 101, #
"responseLength" : 74659, #
"millis" : 19, # ( )
"ts" : ISODate("2014-02-25T02:13:54.899Z"), #
"client" : "127.0.0.1", # ip
"allUsers" : [ ],
"user" : "" #
}
上には次のものがあります.
scanAndOrder:
scanAndOrder , True :MongoDB 。
scanAndOrder False,MongoDB 。 :True: ,False: 。
moved
。 update , , , , , . ,
, .
nmoved:
。
nupdated:
getmoreはgetmore操作であり、getmoreは通常、結果セットの比較的大きなクエリで発生し、最初のqueryは結果の一部を返し、後続の結果はgetmoreによって取得されます.
nscanned(スキャンされた記録数)がnreturned(結果を返す記録数)よりはるかに大きい場合は、インデックスによる記録位置決めの最適化を考慮する.responseLengthが大きすぎると、返される結果セットが大きすぎることを示します.この場合、必要なフィールドだけが必要かどうかを見ます.
2:日常的に使用するクエリー
# 10
db.system.profile.find().limit(10).sort({ ts : -1 }).pretty()
# , command
db.system.profile.find( { op: { $ne : 'command' } } ).pretty()
#
db.system.profile.find( { ns : 'mydb.test' } ).pretty()
# 5
db.system.profile.find( { millis : { $gt : 5 } } ).pretty()
#
db.system.profile.find(
{
ts : {
$gt : new ISODate("2012-12-09T03:00:00Z") ,
$lt : new ISODate("2012-12-09T03:40:00Z")
}
}
).pretty()
# , ,
db.system.profile.find(
{
ts : {
$gt : new ISODate("2011-07-12T03:00:00Z") ,
$lt : new ISODate("2011-07-12T03:40:00Z")
}
},
{ user : 0 }
).sort( { millis : -1 } )
まとめ:
Profiling機能は効率に影響を与えるに違いないが、systemを使用しているため、あまり深刻ではない.記録するprofileはcapped collectionというcollectionの操作にはいくつかの制限と特徴がありますが、効率が高いので、使用時にこの機能を開くことができ、ずっと開く必要はありません.