7. How do you find a chicken recipe?
• An unindexed cookbook might be quite a
page turner.
• Probably not what you want, though.
Monday, October 15, 12
8. I know, I’ll use an index!
Monday, October 15, 12
11. How do you find a quick chicken recipe?
Monday, October 15, 12
12. Let’s imagine a compound index
ingredient cooking page
time
... ... ...
chicken 15 min 182, 200
chicken 25 min 199
chicken 30 min 289,316,320
chicken 45 min 290, 291,
354
... ... ...
Monday, October 15, 12
13. Consider the ordering of index keys
Aardvark, 20 min Chicken, 15 min Zuchinni, 45 min
Chicken, 25 min
Chicken, 30 min
Chicken, 45 min
Monday, October 15, 12
14. How about a low-calorie chicken recipe?
Monday, October 15, 12
15. Let’s imagine a 2nd compound index
ingredient calories page
... ... ...
chicken 250 199, 316
chicken 300 289,291
chicken 425 320
... ... ...
Monday, October 15, 12
16. How about a quick, low-calorie recipe?
Monday, October 15, 12
17. Let’s imagine a last compound index
calories cooking time page
... ... ...
250 25 min 199
250 30 min 316
300 25 min 289
300 45 min 291
425 30 min 320
... ... ...
How do you find dishes from 250 to 300 calories that cook from
30 to 40 minutes?
Monday, October 15, 12
18. Consider the ordering of index keys
250 cal, 250 cal, 300 cal, 300 cal, 425 cal,
25 min 30 min 25 min 45 min 30 min
How do you find dishes from 250 to 300 calories that cook from
30 to 40 minutes?
4 index entries will be scanned, but only 1 will match!
Monday, October 15, 12
19. Range queries using an index on A, B
• A is a range
• A is constant, B is a range
• A is constant, order by B
• A is range, B is constant/range
• B is constant/range, A unspecified
Monday, October 15, 12
24. All this is relevant to MongoDB.
• MongoDB’s indexes are B-Trees, which are
designed for range queries.
• Generally, the best index for your queries is
going to be a compound index.
• Every additional index slows down inserts &
removes, and may slow updates.
Monday, October 15, 12
30. Key info about MongoDB’s indexes
• A collection may have at most 64 indexes.
Monday, October 15, 12
31. Key info about MongoDB’s indexes
• A collection may have at most 64 indexes.
• “_id” index is automatic
(except capped collections before 2.2)
Monday, October 15, 12
32. Key info about MongoDB’s indexes
• A collection may have at most 64 indexes.
• “_id” index is automatic
(except capped collections before 2.2)
• All queries can use just 1 index
(except $or queries).
Monday, October 15, 12
33. Key info about MongoDB’s indexes
• A collection may have at most 64 indexes.
• “_id” index is automatic
(except capped collections before 2.2)
• All queries can use just 1 index
(except $or queries).
• The maximum index key size is 1024 bytes.
Monday, October 15, 12
34. Indexes get used where you’d expect
• db.foo.find({x : 42})
• db.foo.find({x : {$in : [42,52]}})
• db.foo.find({x : {$lt : 42})
• update, findAndModify that select on x,
• count, distinct,
• $match in aggregation
• left-anchored regexp, e.g. /^Kev/
Monday, October 15, 12
35. But indexes aren’t always helpful
• Most negations: $not, $nin, $ne
• Some corner cases: $mod, $where
• Matching most regular expressions, e.g. /a/
or /foo/i
Monday, October 15, 12
42. The Query Optimizer
• For each “type” of query, mongoDB
periodically tries all useful indexes.
• Aborts as soon as one plan wins.
• Winning plan is temporarily cached.
Monday, October 15, 12
44. Which plan wins? Explain!
> db.foo.find( { t: { $lt : 40 } } ).explain( )
{
"cursor" : "BtreeCursor t_1" ,
"n" : 42, Pay attention to the
“nscannedObjects: 42
"nscanned" : 42, ratio n/nscanned!
...
"millis" : 0,
...
}
Monday, October 15, 12
45. Think you know better? Give us a hint
> db.foo.find( { t: { $lt : 40 } } ).hint( { _id : 1} )
Monday, October 15, 12
46. Recording slow queries
> db.setProfilingLevel( n , slowms=100ms )
n=0 profiler off
n=1 record queries longer than slowms
n=2 record all queries
> db.system.profile.find()
Monday, October 15, 12
48. Background index builds
db.foo.ensureIndex( { user : 1 } , { background : true } )
Caveats:
• still resource-intensive
• will build in foreground on secondaries
Monday, October 15, 12
49. Minimizing impact on Replica Sets
for (s in secondaries)
s.restartAsStandalone()
s.buildIndex()
s.restartAsReplSetMember()
s.waitForCatchup()
p.stepDown()
p.restartAsStandalone()
p.buildIndex()
p.restartAsReplSetMember()
Monday, October 15, 12
50. Absent or suboptimal indexes are
the most common avoidable
MongoDB performance problem...
...so take some time and get your
indexes right!
Monday, October 15, 12