Robert Stam, 10gen
MongoDB supports a wide range of indexing options to enable fast querying of your data. In this talk we’ll cover how indexing works, the various indexing options, and cover use cases where each might be useful.
{_id:1} and {_id:2} both match {x:null} db.c.createIndex({x:1},{unique:true, dropDups:true}) keeps first duplicate in natural order and drops the rest • • • • • •
time even when a collection already has data creating an index will block MongoDB unless you specify {background:true} even background creation has an impact recommend you create indexes at off peak times (using a script instead of ensureIndex) • • • • • •
{x:1} db.c.find({x:{$in:[2,3]}}), using index {x:1} db.c.find({"x.a":2}), using index {"x.a":1} matches {_id:1,x:{a:2}} and {_id:2,x:{a:2,b:3}} db.c.find({x:{a:2}}), using index {x:1} matches {_id:1,x:{a:2}}, but not {_id:2,x:{a:2,b:3}} What about: • • • • • • • •
{x:1} db.c.find({x:2}) db.c.find({x:10}) db.c.find({x:{$gt:5}}) db.c.find({x:[2,10]}) db.c.find({x:{$in:[2,5]}}) What about: db.c.find({x:{$all:[2,10]}}) index will be used to lookup all x=2 • • • • • • • • •
db.c.find({x:{$in:[2,3]}}), using index {x:1,y:1} db.c.find().sort({x:1,y:1}), using index {x:1,y:1} db.c.find().sort({x:-1,y:1}), using index {x:1:y- 1} db.c.find({x:2}).sort({y:1}), using index {x:1,y:1} • • • • • •
numbers db.c.find({x:{$not:/a/}}) db.c.find({x:{$gte:0,$lte:10},y:5}), using index {x:1,y:1} will scan from {x:0,y:5} to {x:10,y:5} db.c.find({$where:"this.x == 5"}) • • • • • • •
results are sorted from nearest to farthest db.c.find({x:{$within:{$box:[[40,40], [60,60]]}}}), using index {x:"2d"} db.c.find({x:{$within:{$center:[[50, 50], 10]}}}), using index {x:"2d"} db.c.find({x:{$near:[50, 50]},y:2}), using index {x:"2d",y:1} • • • • • •
have a value for the key currently key must be a single field can behave slightly differently sort only returns documents in the index {$exists:false} won't find any documents you can combine sparse with unique to create a unique constraint that ignores missing values • • • • • • •
Whether it is a covering index or not depends on the query and the fields returned All the fields used in the query AND all the fields returned must be in the index Often that means you must exclude _id from the results (unless _id is in the index) Covering indexes are almost always compound indexes Multikey indexes cannot be covering indexes • • • • • •
for logically equivalent indexes {x:1} and {x:-1} {x:1} and {x:1,unique:true} indexes improve speed of queries but slow down inserts and updates more specific indexes can be more helpful than less specific ones {x:1,y:1} vs {x:1} • • • • • • •
based you can force an index to be used db.c.find({x:2,y:3}).hint({y:1}) uses {y:1} and ignores {x:1} you can force a full collection scan db.c.find({x:2}).hint({$natural:1}) don't rely on order of results unless you use sort • • • • • • • •
100 ms (configurable) records performance info in system.profile query system.profile like any other collection profiling impacts performance but not severely • • • • • •
inserts and updates Experiment: use explain and profiling Be careful creating indexes on existing large collections Be careful indexing array fields Consider using compound indexes • • • • • •