The document discusses different explain modes for MongoDB queries and aggregations. It begins with an overview of explain() and query plans, then covers the default "queryPlanner" mode which shows the winning and rejected plans. It also mentions the "executionStats" and "allPlansExecution" modes which provide more runtime statistics. The document aims to help understand how queries and aggregations are executed and troubleshoot performance issues.
3. Goals Of This Talk
Understand how
MongoDB answers
queries
Knowledge
Figure out what's
going on
Debugging
Learn some tricks to
optimize your queries
& aggregations
Best Practices
created by Francielly Constantin Senra from Noun Project
created by Ramon Sandino from Noun Project
4. Non-goals of This Talk
Picking the best
indexes for your
needs
Index Selection
It's mostly extends
naturally
Sharded
ClustersSorry, we don't have
time…
Fixing
Problems
created by ChangHoon Baek from Noun Project
created by David Marioni from Noun Project
created by factor[e] design initiative from Noun Project
41. Is your query using an index to provide the
projection?
//
With
index
//
{nFollowers:
1,
username:
1}.
db.users.find(
{nFollowers:
{$gte:
1000}},
{_id:
0,
nFollowers:
1,
username:
1}
)
✓
PROJECTI
INDEX SCAN
keyPattern: {
nFollowers: 1,
username: 1
}
42. Some Questions We Can Answer
• Is your query using the index you expect?
• Is your query using an index to provide the sort?
• Is your query using an index to provide the projection?
!
43. Some Questions We Can't Yet Answer
• How selective is your index?
• What is the most expensive part of your plan?
• Why was your winning plan chosen?
!
54. Execution Stats: works, advanced, etc.
• These are all PlanStages
• SortStage
• FetchStage
• IndexScanStage FETCH
SORT
INDEX SCAN
keyPattern:
55. Execution Stats: works, advanced, etc.
• These are all PlanStages
• Each PlanStage implements
work()
FETCH
SORT
INDEX SCAN
keyPattern:
56. Execution Stats: works, advanced, etc.
• These are all PlanStages
• Each PlanStage implements
work()
• work() returns one of:
• ADVANCED
• NEED_TIME
• IS_EOF
FETCH
SORT
INDEX SCAN
keyPattern:
68. How selective is your index?
db.tweets.explain("executionStats").find({
createdDate:
{$gte:
<today>},
favorites:
"@eliothorowitz"
})
{
"executionStats"
:
{
"nReturned" : 314,
"totalKeysExamined" : 2704, // < 8% matched
…
}
FETCH
INDEX SCAN
keyPattern: {createdDate:
69. How selective is your index?
db.tweets.explain("executionStats").find({
createdDate:
{$gte:
<today>},
favorites:
"@eliothorowitz"
})
12:02
12:03
12:04
12:06
…
INDEX SCAN
FETCH
INDEX SCAN
keyPattern: {createdDate:
70. How selective is your index?
db.tweets.explain("executionStats").find({
createdDate:
{$gte:
<today>},
favorites:
"@eliothorowitz"
})
12:02
{createdDate:
12:02,
favorites:
[
"@MongoDB",
"@taylorswift"
]}
12:03
12:04
12:06
…
FETCH
FETCH
filter: {
favorites:
"@eliothorowitz"
INDEX SCAN
keyPattern: {createdDate:
71. How selective is your index?
db.tweets.explain("executionStats").find({
createdDate:
{$gte:
<today>},
favorites:
"@eliothorowitz"
})
12:03
12:02
12:04
12:06
…
{createdDate:
12:03,
favorites:
[
"@eliothorowitz",
"@taylorswift"
]}
FETCH
FETCH
filter: {
favorites:
"@eliothorowitz"
INDEX SCAN
keyPattern: {createdDate:
73. What's the most expensive part of your plan?
db.tweets.explain("executionStats").find({
createdDate:
{$gte:
<today>},
favorites:
"@eliothorowitz"
})
FETCH
filter: {
favorites:
"@eliothorowitz"
INDEX SCAN
keyPattern: {createdDate:
74. What's the most expensive part of your plan?
db.tweets.explain("executionStats").find(…)
FETCH
executionTimeMillisEstimate: 431
INDEX SCAN
executionTimeMillisEstimate:
75. What's the most expensive part of your plan?
db.tweets.explain("executionStats").find(…)
FETCH
works: 2705
advanced: 314
needTime: 2391
//
314/2705
≈
8%
INDEX SCAN
76. Some Questions We Can Answer
• Is your query using the index you expect?
• Is your query using an index to provide the sort?
• Is your query using an index to provide the projection?
• How selective is your index?
• Which part of your plan is the most expensive?
!
77. Some Questions We Can't Yet Answer
• Why was your winning plan chosen?
!
78. Why was your winning plan chosen?
db.tweets.explain("executionStats").find({
createdDate:
{$gte:
<today>},
favorites:
"@eliothorowitz"
})
• We had an index on {favorites: 1}, would that have been faster?
!
97. Aggregation Pipelines
• Like PlanStages, input of one stage feeds into the next
• db.tweets.aggregate([
{$match:
{hashtag:
"#MDBW16}},
{$group:
{
_id:
"$author",
nTweets:
{$sum:
1}
}}
])
MATCH GROUP{…}{…}{…} {…}
98. db.tweets.aggregate([
{$match:
{hashtag:
"#MDBW16}},
{$group:
{
_id:
"$author",
nTweets:
{$sum:
1}
}}
])
Collection Scan?!? Are you
kidding me??
Aggregation Pipelines
MATCH GROUP{…}{…}{…} {…}
99. db.tweets.aggregate([
{$match:
{hashtag:
"#MDBW16}},
{$group:
{
_id:
"$author",
nTweets:
{$sum:
1}
}}
])
Collection Scan?!? Are you
kidding me??
Aggregation Pipelines
MATCH GROUP{…}{…}{…} {…}
127. Aggregation: Summary
• Explain output includes query section
• Sometimes the query is doing a lot of your work
• We don't always execute the stages in the order you specified
128. Summary
Understand how
MongoDB answers
queries
Knowledge
Figure out what's
going on
Debugging
Learn some tricks to
optimize your queries
& aggregations
Best Practices
created by Francielly Constantin Senra from Noun Project
created by Ramon Sandino from Noun Project