Vous êtes sur la page 1sur 45

Indexing

Alvin Richards - alvin@10gen.com

Whats Easy About MongoDB Indexing?

Its almost the same as in your RDBMS

Whats Hard About MongoDB Indexing?

Its almost the same as in your RDBMS

Indexes Maintain Order


Index on a: ascending {a: 0, b: 9} {a: 2, b: 0} {a: 3, b: 2} {a: 3, b: 7} {a: 3, b: 5} {a: 7, b: 1} {a: 9, b: 1} Index on a: ascending, b: descending {a: 0, b: 9} {a: 2, b: 0} {a: 3, b: 7} {a: 3, b: 5} {a: 3, b: 2} {a: 7, b: 1} {a: 9, b: 1}

Query for {a: 7}


Index on a: ascending
With Index
[5, 10) [-

, 5)

[10,

[-

, 5) buckets

[5, 7)

[7, 9)

[9, 10)

[10,

) buckets

{...} {...} {...} {...} {...} {...} {...} {...} {...} {...} {...}

Without index - Scan

Creating Indexes
An index on _id is automatic. For more use ensureIndex: db.blogs.ensureIndex({author: 1}) 1 = ascending -1 = descending

Compound Indexes
db.blogs.save({ author: "James", ts: new Date() ... }); db.blogs.ensureIndex({author: 1, ts: -1})

Unique Indexes
db.blogs.save({ author: "James", title: "My first blog" ... }); db.blogs.ensureIndex({title: 1}, {unique: true})

Indexing Embedded Documents


db.blogs.save({ title: "My First blog", stats : { views: 0, followers: 0 } }); db.blogs.ensureIndex({"stats.followers": -1}) db.blogs.find({"stats.followers": {$gt: 500}})

Indexing Embedded Arrays


db.blogs.save({ title: "My First blog", comments: [ {author: "James", ts : new Date()} ] }); db.blogs.ensureIndex({"comments.author": 1}) db.blogs.find({"comments.author": "James"})

Multikeys
db.blogs.save({ title: "My Second blog", tags: ["mongodb", "NoSQL"] }); db.blogs.ensureIndex({tags: 1}) db.blogs.find({tags: "NoSQL"})

Covered Indexes
From 1.8.0 Query resolved in index only Need to exclude _id from items projected
db.blogs.save({ author: "James", title: "My first blog" }); db.blogs.ensureIndex({author: 1}) db.blogs.find({author: "James"}, {author: 1, _id:0}))

Sparse Indexes
From 1.8.0 Key value included if and only if the value is present Reduces size of index Limited to a single field
db.blogs.ensureIndex({loc: 1}, {sparse: true}) // loc key stored for Ben & Sarah only db.blogs.save({author: "Jim"}) db.blogs.save({author: "Ben", loc: null}) db.blogs.save({author: "Sarah", loc: "CA"})

Unique Sparse Indexes


Null and not-present are different
db.blogs.ensureIndex({title:1}, {sparse:true,unique:true}); db.blogs.save({title:"MongoDB for beginners"}) // Can only have a single null value db.blogs.save({title:null}) db.blogs.save({title:null}) E11000 duplicate key error index: test.blogs.$title_1 dup key: { : null } // Can have multiple missing values db.blogs.save({author:"James"}) db.blogs.save({author:"Bob"})

New in 2.0.0 25% smaller, 25% faster All new indexes created in new format Index keys increase to 1024 bytes (from 812 bytes) Old indexes retained "as is"
> db.blogs.ensureIndex({tags:-1}); > db.blogs.getIndexes() ... { "v" : 1, "key" : { "tags" : -1 } ... // Can still create indexes in older format > db.blogs.ensureIndex({tags:-1}, {v:0});

Indexes in 2.0

When are {v:1} indexes created?


Creating an index
> db.blogs.ensureIndex({author:1}) > db.blogs.ensureIndex({author:1}, {v:1})

Creating a new Replica Set member (initial sync)

When are {v:0} converted to {v:1}?


Reindexing
> db.blogs.reIndex()

Repair database
> db.repairDatabase();

Compact command
> db.blogs.runCommand( "compact" )

Geospatial
Geo hash stored in B-Tree First two values indexed
db.blogs.save({ loc: { long: 40.739037, lat: 40.739037 } }); db.blogs.save({ loc: [40.739037, 40.739037] }); db.blogs.ensureIndex({"loc": "2d"})

Geospatial in 2.0
Multi-location indexes for a single document $near may return the document for each index match $within will return a document once and once only
> db.places.insert({ addresses : [ { name : "Home", loc : [55.5, 42.3] }, { name : "Work", loc : [32.3, 44.2] } ] }) > db.places.ensureIndex({ "addresses.loc" : "2d" }) > db.places.insert({ lastSeenAt : [ { x : 45.3, y : 32.2 }, [54.2, 32.3], { lon : 44.2, lat : 38.2 } ] }) > db.places.ensureIndex({ "lastSeenAt" : "2d" })

Other Index Operations


db.blogs.getIndexes() db.blogs.totalIndexSize() db.blogs.dropIndex({"author": 1})

When is an Index Used?


Index on {a: 1} db.c.find({a: 0}) db.c.find({a: {$in: [0, 2]}}) db.c.find({a: {$gt: 5}}) db.c.find().sort({a: -1}) db.c.find({a: 0}, {a:1, _id:0}) db.c.count({a: 0}) db.c.find({a: {$near: [50,50] }}) Partially: db.c.find({b: 0}).sort({a: -1})

When isnt an Index Used?


Index on {a: 1, b: -1}
// Can't use index, since a is not part of query db.c.find({b: 0}) // Not operators will not use an index db.c.find({a: {$ne: 1} }) db.c.find({a: {$nin: [1, 3, 5, 7]} }) // Case insensitive regex will not use an index db.c.find({a: /^h/i})

Picking an index
db.c.ensureIndex({x:1}) db.c.ensureIndex({y:-1}) db.c.find({x: 10, y: foo})
scan terminated index on x

index on y

remember

When are Indexes Needed?


Frequently used queries Low response time Avoid full collection scans

Indexes Slow Down Writes


Indexes take up space Index maintenance will cause writes

Does my query use an Index?


db.blogs.find({title:"My blog"}).explain();

Explain - Scan all documents


db.blogs.find({title:"My blog"}).explain(); { "cursor" : "BasicCursor", "indexBounds" : {} "nscanned" : 57594, "nscannedObjects" : 57594, "n" : 3, "millis" : 108 }

Explain - Index used


db.blogs.ensureIndex({title: 1}); db.blogs.find({title: "My blog"}).explain(); { "cursor" : "BtreeCursor x_1", "indexBounds" : {...}, "nscanned" : 123, "nscannedObjects" : 123, "n" : 10, "millis" : 4 }

Explain - Covered Index used


db.blogs.ensureIndex({title: 1}); db.blogs.find({title: "My blog"}, {title: 1, _id: 0}).explain(); { "cursor" : "BtreeCursor x_1", "indexBounds" : {...}, "nscanned" : 123, "nscannedObjects" : 123, "n" : 10, "millis" : 4, "indexOnly" : true }

Index Internals - Equality match


db.c.find({x: 6})

{_id:4,x:6} {_id:1,x:6}

{_id:5,x:6}

Equality match
db.c.find({x:6}).explain() { "cursor" : "BtreeCursor x_1", "nscanned" : 3, "nscannedObjects" : 3, "n" : 3, "millis" : 1, "nYields" : 0, "nChunkSkips" : 0, "isMultiKey" : false, "indexOnly" : false, "indexBounds" : { "x" : [ [ 6, 6 ] ] } }

Equality match
"indexBounds" : { "x" : [ [ 6, 6 ] ] }

Exact match will have an inclusive range

Equality match
"nscanned" : 3, "nscannedObjects" : 3, "n" : 3,
Number of matching documents is 3

Equality match
db.c.find({x: 6})

5 2 1 3 4 6 6 6 9

Full document match


db.c.ensureIndex({x: 1}) db.c.find({x: 6, y: 1})

{y:4,x:6} {y:1,x:6}

{y:5,x:6}

Full document match


db.c.find({x: 6, y: 1}).explain() { "cursor" : "BtreeCursor x_1", "nscanned" : 3, "nscannedObjects" : 3, "n" : 1, "millis" : 1, "nYields" : 0, "nChunkSkips" : 0, "isMultiKey" : false, "indexOnly" : false, "indexBounds" : { "x" : [ [ 6, 6 ] ] } }

Full document match


"indexBounds" : { "x" : [ [ 6, 6 ] ] }

Exact match will have an inclusive range

Full document match


"nscanned" : 3, "nscannedObjects" : 3, "n" : 1,
Documents for all matching keys scanned, but only one document matched on nonindex keys

Range match
db.c.ensureIndex({x: 1}) db.c.find({x:{$gte:4, $lte:7}})

Range match
db.c.find( {x:{$gte:4,$lte:7}} ).explain() { "cursor" : "BtreeCursor x_1", "nscanned" : 4, "nscannedObjects" : 4, "n" : 4, "millis" : 1, "nYields" : 0, "nChunkSkips" : 0, "isMultiKey" : false, "indexOnly" : false, "indexBounds" : { "x" : [ [ 4, 7 ] ] } }

Range match
"indexBounds" : { "x" : [ [ 4, 7 ] ]

Range match will have an inclusive range

Range match
"nscanned" : 4, "nscannedObjects" : 4, "n" : 4,
Number of matching documents is 4

Range match 5 2 1 3 4 6 7 8 9

Mongostat
insert query update delete getmore command flushes mapped vsize res locked % idx miss % 5345 0 0 0 0 1 0 8.75g 11.1g 132m 1 2 230 0 0 0 0 1 0 8.75g 11.1g 132m 1 7 1740 20 0 0 0 2 0 8.75g 11.1g 132m 3 19 0 120 0 0 0 1 0 8.75g 11.1g 132m 0 17 0 117 0 0 0 1 0 8.75g 11.1g 132m 0 16 0 119 0 0 0 1 0 8.75g 11.1g 132m 0 17

download at mongodb.org

Were Hiring !
alvin@10gen.com
conferences, appearances, and meetups
http://www.10gen.com/events

http://bit.ly/mongo@

Facebook | Twitter | LinkedIn


@mongodb

http://linkd.in/joinmongo

Vous aimerez peut-être aussi