SlideShare a Scribd company logo
1 of 211
Download to read offline
@
#MDBlocal
Tips and Tricks for
Effective Indexing
Alex Bevilacqua
Technical Services Engineer
alexbevi
TORONTO
#MDBLocal
• Your data should be accessible … quickly
• When applied properly, indexes can
improve performance as if by …
WHY DOES THIS MATTER?
#MDBLocal
• Working hard can suck and we all want
to do less when possible
• This goes for our database as well
• The less index keys scanned
or documents fetched from disk or cache
… the better!
• Let’s learn how to improve our indexes,
TOGETHER!
WHY DOES THIS MATTER?
#MDBLocal
IT’S ME … MARIO! ALEX!
• Application Developer
• Development Lead
• System Architect
• Technical Services
Engineer
• Author
• MongoDB Fanboy
#MDBLocal
Alex Bevilacqua
Technical Services Engineer
Toronto
Hi Phil!
#MDBLocal
Alex Bevilacqua
Technical Services Engineer
Toronto
I think I found some slow
queries that may be missing
indexes. What should I
know?
Equality Sort Range "Rule"
#MDBLocal
Roadmap
E-S-R Overview
Guidelines:
• Eà R
• Eà S
• Sà R
E-S-R Considerations
Operator Type Checks
Consecutive Index Keys
Exceptions?
#MDBLocal
Roadmap
E-S-R Overview
Guidelines:
• Eà R
• Eà S
• Sà R
E-S-R Considerations
Operator Type Checks
Consecutive Index Keys
Exceptions?
#MDBLocal
E-S-R
The ordering of index keys in a compound index is critically important.
#MDBLocal
E-S-R
The ordering of index keys in a compound index is critically important.
WHY?
#MDBLocal
E-S-R
The ordering of index keys in a compound index is critically important.
E-S-R provides guidance that is useful in most cases:
• Equality first
• Sort next
• Range last
#MDBLocal
E-S-R
The ordering of index keys in a compound index is critically important.
E-S-R provides guidance that is useful in most cases:
• Equality first
• Sort next
• Range last
Nope, I don’t get it.
Equality? Range? ….. Explain!
#MDBLocal
Definitions
Equality Fields
An exact match on a single
value. For example:
• {x:123}
• {x:{$eq:123}}
• {"x.y":123}
Bounds:
"[123.0, 123.0]"
#MDBLocal
Definitions
Equality Fields Sort
The (entire) requested sort.
.sort({a:1, b:-1})
Bounds:
"[MinKey, MaxKey]",
"[MinKey, MaxKey]"
An exact match on a single
value. For example:
• {x:123}
• {x:{$eq:123}}
• {"x.y":123}
Bounds:
"[123.0, 123.0]"
#MDBLocal
Definitions
Equality Fields Sort Range Predicates
Any predicates that are not
exact matches. Some
operators include:
• {z:{$gt:9000}}
• {z:{$lte:1000}}
Bounds:
"[9000.0, inf.0]",
"[-inf.0, 1000.0]"
The (entire) requested sort.
.sort({a:1, b:-1})
Bounds:
"[MinKey, MaxKey]",
"[MinKey, MaxKey]"
An exact match on a single
value. For example:
• {x:123}
• {x:{$eq:123}}
• {"x.y":123}
Bounds:
"[123.0, 123.0]"
#MDBLocal
Roadmap
E-S-R Overview
Guidelines:
• Eà R
• Eà S
• Sà R
E-S-R Considerations
Operator Type Checks
Consecutive Index Keys
Exceptions?
#MDBLocal
Equality
Equality keys are placed first in any order
If present in the query shape,
equality fields should always form the prefix for the index.
#MDBLocal
Equality
Equality keys are placed first in any order
If present in the query shape,
equality fields should always form the prefix for the index.
WHY?
#MDBLocal
Equality
Equality keys are placed first in any order
If present in the query shape,
equality fields should always form the prefix for the index.
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
#MDBLocal
Equality
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
If present in the query shape,
equality fields should always form the prefix for the index.
Equality keys are placed first in any order
#MDBLocal
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
Equality
{gamertag: "Ace", score: 100}
{gamertag: "Ace", score: 99,999}
{gamertag: "Bob", score: 15,000}
{gamertag: "Bob", score: 50,000}
#MDBLocal
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {}
{}{}
100 15,000 50,000 99,999
Ace Bob Bob Ace
{gamertag: "Ace", score: 100}
{gamertag: "Ace", score: 99,999}
{gamertag: "Bob", score: 15,000}
{gamertag: "Bob", score: 50,000}
Equality
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Bob Ace
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
"indexBounds" : {
"score" : [
"(9000.0, inf.0]"
],
"gamertag" : [
"["Ace", "Ace"]"
]
}
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Bob Ace
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
"indexBounds" : {
"score" : [
"(9000.0, inf.0]"
],
"gamertag" : [
"["Ace", "Ace"]"
]
}
gamertag
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Bob Ace
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
"indexBounds" : {
"score" : [
"(9000.0, inf.0]"
],
"gamertag" : [
"["Ace", "Ace"]"
]
}
gamertag
score
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Bob Ace
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
"indexBounds" : {
"score" : [
"(9000.0, inf.0]"
],
"gamertag" : [
"["Ace", "Ace"]"
]
}
gamertag
score
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Bob Ace
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
"indexBounds" : {
"score" : [
"(9000.0, inf.0]"
],
"gamertag" : [
"["Ace", "Ace"]"
]
}
gamertag
score
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Bob Ace
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
"indexBounds" : {
"score" : [
"(9000.0, inf.0]"
],
"gamertag" : [
"["Ace", "Ace"]"
]
}
gamertag
score
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Bob Ace
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
"indexBounds" : {
"score" : [
"(9000.0, inf.0]"
],
"gamertag" : [
"["Ace", "Ace"]"
]
}
gamertag
score
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Bob Ace
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
"indexBounds" : {
"score" : [
"(9000.0, inf.0]"
],
"gamertag" : [
"["Ace", "Ace"]"
]
}
gamertag
score
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Bob Ace
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
"indexBounds" : {
"score" : [
"(9000.0, inf.0]"
],
"gamertag" : [
"["Ace", "Ace"]"
]
}
gamertag
score
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Bob Ace
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
"indexBounds" : {
"score" : [
"(9000.0, inf.0]"
],
"gamertag" : [
"["Ace", "Ace"]"
]
}
gamertag
score
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Bob Ace
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
#MDBLocal
Ace Bob Bob Ace
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
100 99,999 15,000 50,000
{} {} {} {}
Equality
#MDBLocal
100
Ace Bob
99,999 15,000 50,000
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"score" : [
"(9000.0, inf.0]"
],
}
db.games.createIndex({gamertag:1, score:1})
#MDBLocal
100
Ace Bob
99,999 15,000 50,000
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"score" : [
"(9000.0, inf.0]"
],
}
gamertag
db.games.createIndex({gamertag:1, score:1})
#MDBLocal
100
Ace Bob
99,999 15,000 50,000
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"score" : [
"(9000.0, inf.0]"
],
}
gamertag
score
db.games.createIndex({gamertag:1, score:1})
#MDBLocal
100
Ace Bob
99,999 15,000 50,000
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"score" : [
"(9000.0, inf.0]"
],
}
gamertag
score
db.games.createIndex({gamertag:1, score:1})
#MDBLocal
100
Ace Bob
99,999 15,000 50,000
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"score" : [
"(9000.0, inf.0]"
],
}
gamertag
score
db.games.createIndex({gamertag:1, score:1})
#MDBLocal
100
Ace Bob
99,999 15,000 50,000
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
{} {} {} {}
Equality
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"score" : [
"(9000.0, inf.0]"
],
}
gamertag
score
db.games.createIndex({gamertag:1, score:1})
#MDBLocal
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
R
E R
E
Equality before Range
#MDBLocal
Roadmap
E-S-R Overview
Guidelines:
• Eà R
• Eà S
• Sà R
E-S-R Considerations
Operator Type Checks
Consecutive Index Keys
Exceptions?
#MDBLocal
Sort fields are placed next
Placing sort predicates after sequential equality keys allow for the index to:
Provide a non-blocking sort.
Minimize the amount of scanning required.
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
Sort
#MDBLocal
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
Sort
100 15,000 50,000 99,999
Ace Bob Bob Acegamertag
score
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
Sort
100 15,000 50,000 99,999
Ace Bob Bob Ace
{} {} {} {}
gamertag
score
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
Sort
100 15,000 50,000 99,999
Ace Bob Bob Ace
{} {} {} {}
gamertag
score
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
Sort
100 15,000 50,000 99,999
Ace Bob Bob Ace
{1} {} {} {2}
gamertag
score
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
Sort
100 15,000 50,000 99,999
Ace Bob Bob Ace
{1} {} {} {2}
gamertag
score
"indexBounds" : {
"score" : [
"[MinKey, MaxKey]"
],
"gamertag" : [
"["Ace", "Ace"]"
]
}
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
Sort
100 15,000 50,000 99,999
Ace Bob Bob Ace
{1} {} {} {2}
gamertag
score
"indexBounds" : {
"score" : [
"[MinKey, MaxKey]"
],
"gamertag" : [
"["Ace", "Ace"]"
]
}
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
Sort
100 15,000 50,000 99,999
Ace Bob Bob Ace
{1} {} {} {2}
gamertag
score
"indexBounds" : {
"score" : [
"[MinKey, MaxKey]"
],
"gamertag" : [
"["Ace", "Ace"]”
]
}
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
Sort
100 15,000 50,000 99,999
Ace Bob Bob Ace
{1} {} {} {2}
gamertag
score
"indexBounds" : {
"score" : [
"[MinKey, MaxKey]"
],
"gamertag" : [
"["Ace", "Ace"]”
]
}
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
Sort
100 15,000 50,000 99,999
Ace Bob Bob Ace
{1} {} {} {2}
gamertag
score
"indexBounds" : {
"score" : [
"[MinKey, MaxKey]"
],
"gamertag" : [
"["Ace", "Ace"]”
]
}
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
Sort
100 15,000 50,000 99,999
Ace Bob Bob Ace
{1} {} {} {2}
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
gamertag
score
"indexBounds" : {
"score" : [
"[MinKey, MaxKey]"
],
"gamertag" : [
"["Ace", "Ace"]”
]
}
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
Sort
100 15,000 50,000 99,999
Ace Bob Bob Ace
{1} {} {} {2}
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
gamertag
score
"indexBounds" : {
"score" : [
"[MinKey, MaxKey]"
],
"gamertag" : [
"["Ace", "Ace"]”
]
}
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
Sort
100 15,000 50,000 99,999
Ace Bob Bob Ace
{1} {} {} {2}
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
gamertag
score
"indexBounds" : {
"score" : [
"[MinKey, MaxKey]"
],
"gamertag" : [
"["Ace", "Ace"]”
]
}
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
Sort
100 15,000 50,000 99,999
Ace Bob Bob Ace
{1} {} {} {2}
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
gamertag
score
"indexBounds" : {
"score" : [
"[MinKey, MaxKey]"
],
"gamertag" : [
"["Ace", "Ace"]”
]
}
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
Sort
100 15,000 50,000 99,999
Ace Bob Bob Ace
{1} {} {} {2}
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
gamertag
score
"indexBounds" : {
"score" : [
"[MinKey, MaxKey]"
],
"gamertag" : [
"["Ace", "Ace"]”
]
}
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
Sort
100 15,000 50,000 99,999
Ace Bob Bob Ace
{1} {} {} {2}
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
gamertag
score
"indexBounds" : {
"score" : [
"[MinKey, MaxKey]"
],
"gamertag" : [
"["Ace", "Ace"]”
]
}
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
Sort
100 15,000 50,000 99,999
Ace Bob Bob Ace
{1} {} {} {2}
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
gamertag
score
"indexBounds" : {
"score" : [
"[MinKey, MaxKey]"
],
"gamertag" : [
"["Ace", "Ace"]”
]
}
db.games.createIndex({score:1, gamertag:1})
#MDBLocal
Sort
100 15,000 50,000 99,999
Ace Bob Bob Ace
{1} {} {} {2}
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
#MDBLocal
Sort
Ace Bob Bob Ace
100 99,999 15,000 50,000
{1} {2} {} {}
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
#MDBLocal
Sort
100
Ace Bob
99,999 15,000 50,000
{}{1} {2} {}
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
gamertag
score
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
”score" : [
"[MinKey, MaxKey]"
]
}
db.games.createIndex({gamertag:1, score:1})
#MDBLocal
Sort
100
Ace Bob
99,999 15,000 50,000
{}{1} {2} {}
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
gamertag
score
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
”score" : [
"[MinKey, MaxKey]"
]
}
db.games.createIndex({gamertag:1, score:1})
#MDBLocal
Sort
100
Ace Bob
99,999 15,000 50,000
{}{1} {2} {}
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
gamertag
score
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
”score" : [
"[MinKey, MaxKey]"
]
}
db.games.createIndex({gamertag:1, score:1})
#MDBLocal
Sort
100
Ace Bob
99,999 15,000 50,000
{}{1} {2} {}
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
gamertag
score
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
”score" : [
"[MinKey, MaxKey]"
]
}
db.games.createIndex({gamertag:1, score:1})
#MDBLocal
Sort
100
Ace Bob
99,999 15,000 50,000
{}{1} {2} {}
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
gamertag
score
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
”score" : [
"[MinKey, MaxKey]"
]
}
db.games.createIndex({gamertag:1, score:1})
#MDBLocal
Sort
100
Ace Bob
99,999 15,000 50,000
{}{1} {2} {}
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
gamertag
score
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
”score" : [
"[MinKey, MaxKey]"
]
}
db.games.createIndex({gamertag:1, score:1})
#MDBLocal
Sort
100
Ace Bob
99,999 15,000 50,000
{}{1} {2} {}
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
gamertag
score
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
”score" : [
"[MinKey, MaxKey]"
]
}
db.games.createIndex({gamertag:1, score:1})
#MDBLocal
Sort after Equality
S
E S
E
db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
Don’t do this, it may require a full index
scan
#MDBLocal
Roadmap
E-S-R Overview
Guidelines:
• Eà R
• Eà S
• Sà R
E-S-R Considerations
Operator Type Checks
Consecutive Index Keys
Exceptions?
#MDBLocal
Range fields are usually last
This allows them to:
Still participate in filtering the data
But does not force a blocking sort.
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
Range
#MDBLocal
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
R
E R
E
Range after Equality
#MDBLocal
db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
R
E R
E
Range after Equality
Should range come after sort too?
#MDBLocal
R
E R
E
Range after Equality
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Should range come after sort too?
#MDBLocal
R
E R
E
Range
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Bob Ace
*
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
gamertag
score
db.games.createIndex({ …, score:1, gamertag:1})
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Bob Ace
*
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
gamertag
score
db.games.createIndex({ …, score:1, gamertag:1})
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Cali Ace
*
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
gamertag
score
db.games.createIndex({ …, score:1, gamertag:1})
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Cali Ace
*
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
{} {} {} {}{1}{2} {3}
gamertag
score
db.games.createIndex({ …, score:1, gamertag:1})
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Cali Ace
*
{} {2} {3} {1}
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
gamertag
score
"indexBounds" : {
*,
"score" : [
"(9000.0, inf.0]"
],
"gamertag" : [
"[MinKey, MaxKey]"
]
}
db.games.createIndex({ …, score:1, gamertag:1})
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Cali Ace
*
{} {2} {3} {1}
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
gamertag
score
"indexBounds" : {
*,
"score" : [
"(9000.0, inf.0]"
],
"gamertag" : [
"[MinKey, MaxKey]"
]
}
db.games.createIndex({ …, score:1, gamertag:1})
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Cali Ace
*
{} {2} {3} {1}
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
gamertag
score
"indexBounds" : {
*,
"score" : [
"(9000.0, inf.0]"
],
"gamertag" : [
"[MinKey, MaxKey]"
]
}
db.games.createIndex({ …, score:1, gamertag:1})
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Cali Ace
*
{} {2} {3} {1}
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
gamertag
score
"indexBounds" : {
*,
"score" : [
"(9000.0, inf.0]"
],
"gamertag" : [
"[MinKey, MaxKey]"
]
}
db.games.createIndex({ …, score:1, gamertag:1})
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Cali Ace
*
{} {2} {3} {1}
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
gamertag
score
"indexBounds" : {
*,
"score" : [
"(9000.0, inf.0]"
],
"gamertag" : [
"[MinKey, MaxKey]"
]
}
db.games.createIndex({ …, score:1, gamertag:1})
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Cali Ace
*
{} {2} {3} {1}
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
gamertag
score
"indexBounds" : {
*,
"score" : [
"(9000.0, inf.0]"
],
"gamertag" : [
"[MinKey, MaxKey]"
]
}
db.games.createIndex({ …, score:1, gamertag:1})
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Cali Ace
*
{} {2} {3} {1}
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
gamertag
score
"indexBounds" : {
*,
"score" : [
"(9000.0, inf.0]"
],
"gamertag" : [
"[MinKey, MaxKey]"
]
}
db.games.createIndex({ …, score:1, gamertag:1})
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Cali Ace
*
{} {2} {3} {1}
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
gamertag
score
"indexBounds" : {
*,
"score" : [
"(9000.0, inf.0]"
],
"gamertag" : [
"[MinKey, MaxKey]"
]
}
db.games.createIndex({ …, score:1, gamertag:1})
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Cali Ace
*
{} {2} {3} {1}
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
gamertag
score
"indexBounds" : {
*,
"score" : [
"(9000.0, inf.0]"
],
"gamertag" : [
"[MinKey, MaxKey]"
]
}
db.games.createIndex({ …, score:1, gamertag:1})
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Cali Ace
*
{} {2} {3} {1}
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
gamertag
score
"indexBounds" : {
*,
"score" : [
"(9000.0, inf.0]"
],
"gamertag" : [
"[MinKey, MaxKey]"
]
}
db.games.createIndex({ …, score:1, gamertag:1})
#MDBLocal
{2} {3} {1}
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
Blocking SortBlocking
Sort
BS
#MDBLocal
{2}{3}{1}
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
BS
#MDBLocal
100 15,000 50,000 99,999
Ace Bob Cali Ace
*
{} {2} {3} {1}
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
#MDBLocal
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
*
Ace Bob Cali Ace
100 15,000 50,00099,999
{} {1} {2} {3}
#MDBLocal
*
100 15,000 50,00099,999
Ace Bob Cali
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
{} {1} {3}
score
gamertag
"indexBounds" : {
*,
"gamertag" : [
"[MinKey, MaxKey]"
]
"score" : [
"(9000.0, inf.0]"
]
}
db.games.createIndex({ …, gamertag:1, score:1})
{2}
#MDBLocal
*
100 15,000 50,00099,999
Ace Bob Cali
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
{} {1} {3}
score
gamertag
"indexBounds" : {
*,
"gamertag" : [
"[MinKey, MaxKey]"
]
"score" : [
"(9000.0, inf.0]"
]
}
db.games.createIndex({ …, gamertag:1, score:1})
{2}
#MDBLocal
*
100 15,000 50,00099,999
Ace Bob Cali
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
{} {1} {3}
score
gamertag
"indexBounds" : {
*,
"gamertag" : [
"[MinKey, MaxKey]"
]
"score" : [
"(9000.0, inf.0]"
]
}
db.games.createIndex({ …, gamertag:1, score:1})
{2}
#MDBLocal
*
100 15,000 50,00099,999
Ace Bob Cali
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
{} {1} {3}
score
gamertag
"indexBounds" : {
*,
"gamertag" : [
"[MinKey, MaxKey]"
]
"score" : [
"(9000.0, inf.0]"
]
}
db.games.createIndex({ …, gamertag:1, score:1})
{2}
#MDBLocal
*
100 15,000 50,00099,999
Ace Bob Cali
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
{} {1} {3}
score
gamertag
"indexBounds" : {
*,
"gamertag" : [
"[MinKey, MaxKey]"
]
"score" : [
"(9000.0, inf.0]"
]
}
db.games.createIndex({ …, gamertag:1, score:1})
{2}
#MDBLocal
*
100 15,000 50,00099,999
Ace Bob Cali
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
{} {1} {3}
score
gamertag
"indexBounds" : {
*,
"gamertag" : [
"[MinKey, MaxKey]"
]
"score" : [
"(9000.0, inf.0]"
]
}
db.games.createIndex({ …, gamertag:1, score:1})
{2}
#MDBLocal
*
100 15,000 50,00099,999
Ace Bob Cali
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
{} {1} {3}
score
gamertag
"indexBounds" : {
*,
"gamertag" : [
"[MinKey, MaxKey]"
]
"score" : [
"(9000.0, inf.0]"
]
}
db.games.createIndex({ …, gamertag:1, score:1})
{2}
#MDBLocal
*
100 15,000 50,00099,999
Ace Bob Cali
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
{} {1} {3}
score
gamertag
"indexBounds" : {
*,
"gamertag" : [
"[MinKey, MaxKey]"
]
"score" : [
"(9000.0, inf.0]"
]
}
db.games.createIndex({ …, gamertag:1, score:1})
{2}
#MDBLocal
*
100 15,000 50,00099,999
Ace Bob Cali
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
{} {1} {3}
score
gamertag
"indexBounds" : {
*,
"gamertag" : [
"[MinKey, MaxKey]"
]
"score" : [
"(9000.0, inf.0]"
]
}
db.games.createIndex({ …, gamertag:1, score:1})
{2}
#MDBLocal
*
100 15,000 50,00099,999
Ace Bob Cali
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
{} {1} {3}
score
gamertag
"indexBounds" : {
*,
"gamertag" : [
"[MinKey, MaxKey]"
]
"score" : [
"(9000.0, inf.0]"
]
}
db.games.createIndex({ …, gamertag:1, score:1})
{2}
#MDBLocal
*
100 15,000 50,00099,999
Ace Bob Cali
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range
{} {1} {3}
score
gamertag
"indexBounds" : {
*,
"gamertag" : [
"[MinKey, MaxKey]"
]
"score" : [
"(9000.0, inf.0]"
]
}
db.games.createIndex({ …, gamertag:1, score:1})
{2}
#MDBLocal
BS
R S
R
S
db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
Range after Sort
#MDBLocal
Roadmap
E-S-R Overview
Guidelines:
• Eà R
• Eà S
• Sà R
E-S-R Considerations
Operator Type Checks
Consecutive Index Keys
Exceptions?
#MDBLocal
Operator Type Check
Some operators are simple
$eq: Equality
$gte: Range
Others are trickier
#MDBLocal
Operator Type Check - Inequality
Inequality Operators: E, S, or R?
• $ne:123
• $nin:[1,2]
Range!
#MDBLocal
Operator Type Check - Inequality
Inequality Operators: E, S, or R?
• $ne:123
• $nin:[1,2]
Range!
But … how do you know?
#MDBLocal
Operator Type Check - Inequality
Inequality Operators: E, S, or R?
• $ne:123
• $nin:[1,2]
Range!
"indexBounds" : {
"x" : [
"[MinKey, 123.0)",
"(123.0, MaxKey]"
]
}
#MDBLocal
Operator Type Check - Inequality
Range!
"indexBounds" : {
"x" : [
"[MinKey, 123.0)",
"(123.0, MaxKey]"
]
}
50 123 999
#MDBLocal
Operator Type Check - Inequality
Range!
"indexBounds" : {
"x" : [
"[MinKey, 123.0)",
"(123.0, MaxKey]"
]
}
50 123 999
#MDBLocal
Operator Type Check - Inequality
Range!
"indexBounds" : {
"x" : [
"[MinKey, 123.0)",
"(123.0, MaxKey]"
]
}
50 123 999
#MDBLocal
Operator Type Check - Regex
Regex Operators: E, S, or R?
• {str:/car/}
• {str:/^car/i}
Range!
#MDBLocal
Operator Type Check - Regex
Regex Operators: E, S, or R?
• {str:/car/}
• {str:/^car/i}
Range!
#MDBLocal
Operator Type Check - Regex
Regex Operators: E, S, or R?
• {str:/car/}
• {str:/^car/i}
Range!
planecar racecar
#MDBLocal
Operator Type Check - Regex
Regex Operators: E, S, or R?
• {str:/car/}
• {str:/^car/i}
Range!
planecar racecar
#MDBLocal
Operator Type Check - Regex
Regex Operators: E, S, or R?
• {str:/car/}
• {str:/^car/i}
Range!
planecar racecar
#MDBLocal
Operator Type Check - Regex
Regex Operators: E, S, or R?
• {str:/car/}
• {str:/^car/i}
Range!
p???ecar racecar
#MDBLocal
Operator Type Check - Regex
Regex Operators: E, S, or R?
• {str:/car/}
• {str:/^car/i}
Range!
p???ecar racecar
#MDBLocal
Operator Type Check - Regex
Regex Operators: E, S, or R?
• {str:/car/}
• {str:/^car/i}
Range!
#MDBLocal
Operator Type Check - Regex
Regex Operators: E, S, or R?
• {str:/car/}
• {str:/^car/i}
Range!
raincarry
#MDBLocal
Operator Type Check - Regex
Regex Operators: E, S, or R?
• {str:/car/}
• {str:/^car/i}
Range!
raincarry
#MDBLocal
Operator Type Check - Regex
Regex Operators: E, S, or R?
• {str:/car/}
• {str:/^car/i}
Range!
raincarry Carpool
#MDBLocal
Operator Type Check - Regex
Regex Operators: E, S, or R?
• {str:/car/}
• {str:/^car/i}
Range!
raincarry Carpool
#MDBLocal
Operator Type Check - Regex
Regex Operators: E, S, or R?
• {str:/car/}
• {str:/^car/i}
Range!
raincarry Carpool
#MDBLocal
Operator Type Check - Regex
Regex Operators: E, S, or R?
• {str:/car/}
• {str:/^car/i}
Range!
raincarry
Carpoo
l
Woah Woah WOAH …. Since the regex is left
anchored, can’t we skip the middle tree?
#MDBLocal
Operator Type Check - Regex
Regex Operators: E, S, or R?
• {str:/car/}
• {str:/^car/i}
Range!
raincarry
Carpoo
l
Woah Woah WOAH …. Since the regex is left
anchored, can’t we skip the middle tree?
#MDBLocal
Operator Type Check - Regex
Regex Operators: E, S, or R?
• {str:/car/}
• {str:/^car/i}
Range!
cArrycarry
Carpoo
l
Woah Woah WOAH …. Since the regex is left
anchored, can’t we skip the middle tree?
#MDBLocal
Operator Type Check - Regex
Regex Operators: E, S, or R?
• {str:/car/}
• {str:/^car/i}
Range!
cArrycarry
Carpoo
l
Woah Woah WOAH …. Since the regex is left
anchored, can’t we skip the middle tree?
#MDBLocal
Operator Type Check - Regex
Regex Operators: E, S, or R?
• {str:/car/}
• {str:/^car/i}
Range!
cArrycarry
Carpoo
l
#MDBLocal
Operator Type Check - $in
$in filters: E, S, or R?
• {field:{$in:[1,3]}}
… it depends with respect to key
ordering
Alone: a series of Equality matches
Combined: possibly a Range
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}})
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
"[3.0, 3.0]"
]
}
?
1 2 3
C G B F A D
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}})
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
"[3.0, 3.0]"
]
}
?
1 2 3
C G B F A D
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}})
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
"[3.0, 3.0]"
]
}
?
1 2 3
C G B F A D
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}})
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
"[3.0, 3.0]"
]
}
?
1 2 3
C G B F A D
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}})
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
"[3.0, 3.0]"
]
}
?
1 2 3
C G B F A D
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}})
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
"[3.0, 3.0]"
]
}
?
1 2 3
C G B F A D
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}})
.sort({sortField:1})
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
"[3.0, 3.0]"
]
}
?
1 2 3
C G B F A D
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}})
.sort({sortField:1})
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
"[3.0, 3.0]"
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
?
1 2 3
C G B F A D
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}})
.sort({sortField:1})
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
"[3.0, 3.0]"
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
?
1 2 3
C G B F A D
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}})
.sort({sortField:1})
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
"[3.0, 3.0]"
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
?
1 2 3
C G B F A D
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}})
.sort({sortField:1})
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
"[3.0, 3.0]"
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
?
1 2 3
C G B F A D
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}})
.sort({sortField:1})
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
"[3.0, 3.0]"
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
?
1 2 3
C G B F A D
BS
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}})
.sort({sortField:1})
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
"[3.0, 3.0]"
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
?
1 2 3
C G B F A D
BS
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}})
.sort({sortField:1})
?
1 2 3
C G B F A D
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}}).sort({sortField:1}) ?
1 2 3
C G B F A D
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}}).sort({sortField:1})
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
?
1 2 3
C G B F A D
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}}).sort({sortField:1})
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
?
1 2 3
C G B F A D
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}}).sort({sortField:1})
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
?
1 2 3
C G B F A D
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}}).sort({sortField:1})
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
?
1 2 3
C G B F A D
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}}).sort({sortField:1})
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
?
1 2 3
C G B F A D
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}}).sort({sortField:1})
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
"indexBounds" : {
"field" : [
"[3.0, 3.0]",
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
?
1 2 3
C G B F A D
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}}).sort({sortField:1})
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
"indexBounds" : {
"field" : [
"[3.0, 3.0]",
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
?
1 2 3
C G B F A D
?
1 2 3
C G B F A D
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}}).sort({sortField:1})
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
"indexBounds" : {
"field" : [
"[3.0, 3.0]",
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
?
1 2 3
C G B F A D
?
1 2 3
C G B F A D
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}}).sort({sortField:1})
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
"indexBounds" : {
"field" : [
"[3.0, 3.0]",
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
?
1 2 3
C G B F A D
?
1 2 3
C G B F A D
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
Operator Type Check - $in
.find({field:{$in:[1,3]}}).sort({sortField:1})
"indexBounds" : {
"field" : [
"[1.0, 1.0]",
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
"indexBounds" : {
"field" : [
"[3.0, 3.0]",
],
"sortField" : [
"[MinKey, MaxKey]"
]
}
?
1 2 3
C G B F A D
?
1 2 3
C G B F A D
{2} {4} {1} {3}
Sort Merge
db.coll.createIndex({field:1, sortField:1})
#MDBLocal
BS
S M
Operator Type Check - $in
#MDBLocal
Roadmap
E-S-R Overview
Guidelines:
• Eà R
• Eà S
• Sà R
E-S-R Considerations
Operator Type Checks
Consecutive Index Keys
Exceptions?
#MDBLocal
Consecutive Index Keys
Given Indexes:
{gamertag:1, date:1, game:1}
{gamertag:1, game:1, date:1}
Which one is “better”?
It depends on the query shape(s)!
Consider the query:
.find({
gamertag:"Ace",
game: "Halo”
})
#MDBLocal
Consecutive Index Keys
.find({
gamertag:"Ace",
game: "Halo”
})
#MDBLocal
Consecutive Index Keys
Ace
Mario Halo
2016 2017
Mario Halo
2018 2019
.find({
gamertag:"Ace",
game: "Halo”
})
db.games.createIndex({gamertag:1, date:1, game:1})
#MDBLocal
Consecutive Index Keys
Ace
Mario Halo
2016 2017
Mario Halo
2018 2019
.find({
gamertag:"Ace",
game: "Halo”
})
{} {} {} {}
db.games.createIndex({gamertag:1, date:1, game:1})
#MDBLocal
Consecutive Index Keys
Ace
Mario Halo
2016 2017
Mario Halo
2018 2019
.find({
gamertag:"Ace",
game: "Halo”
})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[MinKey, MaxKey]"
],
"game" : [
"["Halo", "Halo"]"
]
}
{} {} {} {}
db.games.createIndex({gamertag:1, date:1, game:1})
#MDBLocal
Consecutive Index Keys
Ace
Mario Halo
2016 2017
Mario Halo
2018 2019
.find({
gamertag:"Ace",
game: "Halo”
})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[MinKey, MaxKey]"
],
"game" : [
"["Halo", "Halo"]"
]
}
{} {} {} {}
db.games.createIndex({gamertag:1, date:1, game:1})
#MDBLocal
Consecutive Index Keys
Ace
Mario Halo
2016 2017
Mario Halo
2018 2019
.find({
gamertag:"Ace",
game: "Halo”
})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[MinKey, MaxKey]"
],
"game" : [
"["Halo", "Halo"]"
]
}
{} {} {} {}
db.games.createIndex({gamertag:1, date:1, game:1})
#MDBLocal
Consecutive Index Keys
Ace
Mario Halo
2016 2017
Mario Halo
2018 2019
.find({
gamertag:"Ace",
game: "Halo”
})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[MinKey, MaxKey]"
],
"game" : [
"["Halo", "Halo"]"
]
}
{} {} {} {}
db.games.createIndex({gamertag:1, date:1, game:1})
#MDBLocal
Consecutive Index Keys
Ace
Mario Halo
2016 2017
Mario Halo
2018 2019
.find({
gamertag:"Ace",
game: "Halo”
})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[MinKey, MaxKey]"
],
"game" : [
"["Halo", "Halo"]"
]
}
{} {} {} {}
db.games.createIndex({gamertag:1, date:1, game:1})
#MDBLocal
Consecutive Index Keys
Ace
Mario Halo
2016 2017
Mario Halo
2018 2019
.find({
gamertag:"Ace",
game: "Halo”
})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[MinKey, MaxKey]"
],
"game" : [
"["Halo", "Halo"]"
]
}
{} {} {} {}
db.games.createIndex({gamertag:1, date:1, game:1})
#MDBLocal
Consecutive Index Keys
Ace
Mario Halo
2016 2017
Mario Halo
2018 2019
.find({
gamertag:"Ace",
game: "Halo”
})
{} {}
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[MinKey, MaxKey]"
],
"game" : [
"["Halo", "Halo"]"
]
}
{} {}
db.games.createIndex({gamertag:1, date:1, game:1})
#MDBLocal
Consecutive Index Keys
Ace
Mario Halo
2016 2017
Mario Halo
2018 2019
.find({
gamertag:"Ace",
game: "Halo”
})
{} {}
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[MinKey, MaxKey]"
],
"game" : [
"["Halo", "Halo"]"
]
}
{} {}
db.games.createIndex({gamertag:1, date:1, game:1})
#MDBLocal
Consecutive Index Keys
Ace
Mario Halo
2016 2017
Mario Halo
2018 2019
.find({
gamertag:"Ace",
game: "Halo”
})
{} {}
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[MinKey, MaxKey]"
],
"game" : [
"["Halo", "Halo"]"
]
}
{} {}
db.games.createIndex({gamertag:1, date:1, game:1})
#MDBLocal
Consecutive Index Keys
Ace
Mario Halo
2016 2017
Mario Halo
2018 2019
.find({
gamertag:"Ace",
game: "Halo”
})
{} {}
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[MinKey, MaxKey]"
],
"game" : [
"["Halo", "Halo"]"
]
}
{} {}
db.games.createIndex({gamertag:1, date:1, game:1})
#MDBLocal
Consecutive Index Keys
Ace
Mario Halo
2016 2017
Mario Halo
2018 2019
.find({
gamertag:"Ace",
game: "Halo”
})
{} {}
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[MinKey, MaxKey]"
],
"game" : [
"["Halo", "Halo"]"
]
}
{} {}
db.games.createIndex({gamertag:1, date:1, game:1})
#MDBLocal
Consecutive Index Keys
.find({
gamertag:"Ace",
game: "Halo”
})
{} {} {} {}
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[MinKey, MaxKey]"
],
"game" : [
"["Halo", "Halo"]"
]
}
Halo
Ace
Mario Halo
2016 2017
Mario
2018 2019
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"game" : [
"["Halo", "Halo"]"
]
}
db.games.createIndex({gamertag:1, game:1})
#MDBLocal
Ace
2016 2017Mario2018 2019Halo
Consecutive Index Keys
.find({
gamertag:"Ace",
game: "Halo”
})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"game" : [
"["Halo", "Halo"]"
]
}
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"game" : [
"["Halo", "Halo"]"
],
"date" : [
"[MinKey, MaxKey]"
]
}
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"game" : [
"["Halo", "Halo"]"
]
}
{}{} {}{}
db.games.createIndex({gamertag:1, game:1, date:1})
#MDBLocal
R
E
E E
E
E
E
Consecutive Index Keys
R
Look familiar? This is equality after range!
#MDBLocal
Roadmap
E-S-R Overview
Guidelines:
• Eà R
• Eà S
• Sà R
E-S-R Considerations
Operator Type Checks
Consecutive Index Keys
Exceptions?
#MDBLocal
Exceptions
Is the E-S-R “rule” always optimal?
Nope.
Consider the following query:
db.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
#MDBLocal
Exceptionsdb.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
gamertag
score
date
{} {} {} {1} {2}
db.games.createIndex({gamertag:1, score:1, date:1})
#MDBLocal
Exceptionsdb.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
gamertag
score
date
{} {} {}
db.games.createIndex({gamertag:1, score:1, date:1})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"score" : [
"[MinKey, MaxKey]"
],
"date" : [
"[2019.0, inf.0]"
]
}
{1} {2}
#MDBLocal
Exceptionsdb.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
gamertag
score
date
{} {} {}
db.games.createIndex({gamertag:1, score:1, date:1})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"score" : [
"[MinKey, MaxKey]"
],
"date" : [
"[2019.0, inf.0]"
]
}
{1} {2}
#MDBLocal
Exceptionsdb.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
gamertag
score
date
{} {} {}
db.games.createIndex({gamertag:1, score:1, date:1})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"score" : [
"[MinKey, MaxKey]"
],
"date" : [
"[2019.0, inf.0]"
]
}
{1} {2}
#MDBLocal
Exceptionsdb.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
gamertag
score
date
{} {} {}
db.games.createIndex({gamertag:1, score:1, date:1})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"score" : [
"[MinKey, MaxKey]"
],
"date" : [
"[2019.0, inf.0]"
]
}
{1} {2}
#MDBLocal
Exceptionsdb.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
gamertag
score
date
{} {} {}
db.games.createIndex({gamertag:1, score:1, date:1})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"score" : [
"[MinKey, MaxKey]"
],
"date" : [
"[2019.0, inf.0]"
]
}
{1} {2}
#MDBLocal
Exceptionsdb.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
gamertag
score
date
{} {} {}
db.games.createIndex({gamertag:1, score:1, date:1})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"score" : [
"[MinKey, MaxKey]"
],
"date" : [
"[2019.0, inf.0]"
]
}
{1} {2}
#MDBLocal
Exceptionsdb.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
gamertag
score
date
{} {} {}
db.games.createIndex({gamertag:1, score:1, date:1})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"score" : [
"[MinKey, MaxKey]"
],
"date" : [
"[2019.0, inf.0]"
]
}
{1} {2}
#MDBLocal
Exceptionsdb.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
gamertag
score
date
{} {} {}
db.games.createIndex({gamertag:1, score:1, date:1})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"score" : [
"[MinKey, MaxKey]"
],
"date" : [
"[2019.0, inf.0]"
]
}
{1} {2}
#MDBLocal
Exceptionsdb.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
gamertag
score
date
{} {} {}
db.games.createIndex({gamertag:1, score:1, date:1})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"score" : [
"[MinKey, MaxKey]"
],
"date" : [
"[2019.0, inf.0]"
]
}
{1} {2}
#MDBLocal
Exceptionsdb.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
gamertag
score
date
{} {} {}
db.games.createIndex({gamertag:1, score:1, date:1})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"score" : [
"[MinKey, MaxKey]"
],
"date" : [
"[2019.0, inf.0]"
]
}
{1} {2}
#MDBLocal
Exceptionsdb.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
gamertag
score
date
{} {} {}
db.games.createIndex({gamertag:1, score:1, date:1})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"score" : [
"[MinKey, MaxKey]"
],
"date" : [
"[2019.0, inf.0]"
]
}
{1} {2}
#MDBLocal
Exceptionsdb.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
gamertag
score
date
{} {} {}
db.games.createIndex({gamertag:1, score:1, date:1})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"score" : [
"[MinKey, MaxKey]"
],
"date" : [
"[2019.0, inf.0]"
]
}
{1} {2}
#MDBLocal
Exceptionsdb.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
gamertag
score
date
{} {} {}
db.games.createIndex({gamertag:1, score:1, date:1})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"score" : [
"[MinKey, MaxKey]"
],
"date" : [
"[2019.0, inf.0]"
]
}
{1} {2}
#MDBLocal
Exceptionsdb.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
gamertag
score
date
{} {} {}
db.games.createIndex({gamertag:1, score:1, date:1})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"score" : [
"[MinKey, MaxKey]"
],
"date" : [
"[2019.0, inf.0]"
]
}
{1} {2}
#MDBLocal
Exceptionsdb.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
gamertag
score
date
{} {} {}
"executionStats" : {
"nReturned" : 2,
"executionTimeMillis" : 23,
"totalKeysExamined" : 9001,
"totalDocsExamined" : 2,
db.games.createIndex({gamertag:1, score:1, date:1})
{1} {2}
#MDBLocal
Exceptionsdb.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
1 5,000 9,0012 9,000
… …
2001 2000 2015 2019 2019
#MDBLocal
Exceptionsdb.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
2001 2000 2015 2019 2019
{score:2} {score:1} {score:5000} {score:9001} {score:9000}
… …
gamertag
date
#MDBLocal
Exceptionsdb.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
… …
2000 2001 2015 2019 2019
{score:2} {score:1} {score:5000} {score:9001} {score:9000}
gamertag
date
db.games.createIndex({gamertag:1, date:1})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[2019.0, inf.0]"
]
}
#MDBLocal
Exceptionsdb.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
… …
2000 2001 2015 2019 2019
{score:2} {score:1} {score:5000} {score:9001} {score:9000}
gamertag
date
db.games.createIndex({gamertag:1, date:1})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[2019.0, inf.0]"
]
}
#MDBLocal
Exceptionsdb.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
… …
2000 2001 2015 2019 2019
{score:2} {score:1} {score:5000} {score:9001} {score:9000}
gamertag
date
db.games.createIndex({gamertag:1, date:1})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[2019.0, inf.0]"
]
}
#MDBLocal
Exceptionsdb.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
… …
2000 2001 2015 2019 2019
{score:2} {score:1} {score:5000} {score:9001} {score:9000}
gamertag
date
db.games.createIndex({gamertag:1, date:1})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[2019.0, inf.0]"
]
}
#MDBLocal
Exceptionsdb.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
… …
2000 2001 2015 2019 2019
{score:2} {score:1} {score:5000} {score:9001} {score:9000}
gamertag
date
db.games.createIndex({gamertag:1, date:1})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[2019.0, inf.0]"
]
}
#MDBLocal
Exceptionsdb.games
.find({gamertag:"Ace", date:{$gte:2019}})
.sort({score:1})
Ace
… …
2000 2001 2015 2019 2019
{score:2} {score:1} {score:5000}
gamertag
date
{score:9001} {score:9000}
BS
"executionStats" : {
"nReturned" : 2,
"executionTimeMillis" : 0,
"totalKeysExamined" : 2,
"totalDocsExamined" : 2,
"executionStats" : {
"nReturned" : 2,
"executionTimeMillis" : 0,
"totalKeysExamined" : 2,
"totalDocsExamined" : 2,
"executionStages" : {
"stage" : "SORT",
"memUsage" : 154,
"memLimit" : 33554432,
db.games.createIndex({gamertag:1, date:1})
"indexBounds" : {
"gamertag" : [
"["Ace", "Ace"]"
],
"date" : [
"[2019.0, inf.0]"
]
}
#MDBLocal
Exceptions
……… …
BS
S
R
E
R
E
Summary
#MDBLocal
E-S-R Guidance
A good starting place applicable to
most use cases
Place keys in the following order:
Equality first
Sort next
Range last
Remember:
• Some operators may be range
instead of equality
• Having consecutive keys used in
the index is important
• Specifics about your data set may
need a different approach
Thank You!
MongoDB .local Toronto 2019: Tips and Tricks for Effective Indexing
MongoDB .local Toronto 2019: Tips and Tricks for Effective Indexing

More Related Content

What's hot

The MySQL Query Optimizer Explained Through Optimizer Trace
The MySQL Query Optimizer Explained Through Optimizer TraceThe MySQL Query Optimizer Explained Through Optimizer Trace
The MySQL Query Optimizer Explained Through Optimizer Traceoysteing
 
Fast querying indexing for performance (4)
Fast querying   indexing for performance (4)Fast querying   indexing for performance (4)
Fast querying indexing for performance (4)MongoDB
 
[Meetup] a successful migration from elastic search to clickhouse
[Meetup] a successful migration from elastic search to clickhouse[Meetup] a successful migration from elastic search to clickhouse
[Meetup] a successful migration from elastic search to clickhouseVianney FOUCAULT
 
MongoDB Performance Tuning
MongoDB Performance TuningMongoDB Performance Tuning
MongoDB Performance TuningMongoDB
 
MongoDB WiredTiger Internals
MongoDB WiredTiger InternalsMongoDB WiredTiger Internals
MongoDB WiredTiger InternalsNorberto Leite
 
MySQL Index Cookbook
MySQL Index CookbookMySQL Index Cookbook
MySQL Index CookbookMYXPLAIN
 
ClickHouse Deep Dive, by Aleksei Milovidov
ClickHouse Deep Dive, by Aleksei MilovidovClickHouse Deep Dive, by Aleksei Milovidov
ClickHouse Deep Dive, by Aleksei MilovidovAltinity Ltd
 
A Fast Intro to Fast Query with ClickHouse, by Robert Hodges
A Fast Intro to Fast Query with ClickHouse, by Robert HodgesA Fast Intro to Fast Query with ClickHouse, by Robert Hodges
A Fast Intro to Fast Query with ClickHouse, by Robert HodgesAltinity Ltd
 
Indexing & Query Optimization
Indexing & Query OptimizationIndexing & Query Optimization
Indexing & Query OptimizationMongoDB
 
Streaming Operational Data with MariaDB MaxScale
Streaming Operational Data with MariaDB MaxScaleStreaming Operational Data with MariaDB MaxScale
Streaming Operational Data with MariaDB MaxScaleMariaDB plc
 
ProxySQL High Avalability and Configuration Management Overview
ProxySQL High Avalability and Configuration Management OverviewProxySQL High Avalability and Configuration Management Overview
ProxySQL High Avalability and Configuration Management OverviewRené Cannaò
 
PostgreSql query planning and tuning
PostgreSql query planning and tuningPostgreSql query planning and tuning
PostgreSql query planning and tuningFederico Campoli
 
Histograms in MariaDB, MySQL and PostgreSQL
Histograms in MariaDB, MySQL and PostgreSQLHistograms in MariaDB, MySQL and PostgreSQL
Histograms in MariaDB, MySQL and PostgreSQLSergey Petrunya
 
MongoDB - Aggregation Pipeline
MongoDB - Aggregation PipelineMongoDB - Aggregation Pipeline
MongoDB - Aggregation PipelineJason Terpko
 
Inside MongoDB: the Internals of an Open-Source Database
Inside MongoDB: the Internals of an Open-Source DatabaseInside MongoDB: the Internals of an Open-Source Database
Inside MongoDB: the Internals of an Open-Source DatabaseMike Dirolf
 
ReadConcern and WriteConcern
ReadConcern and WriteConcernReadConcern and WriteConcern
ReadConcern and WriteConcernMongoDB
 
Reading the .explain() Output
Reading the .explain() OutputReading the .explain() Output
Reading the .explain() OutputMongoDB
 

What's hot (20)

MongodB Internals
MongodB InternalsMongodB Internals
MongodB Internals
 
The MySQL Query Optimizer Explained Through Optimizer Trace
The MySQL Query Optimizer Explained Through Optimizer TraceThe MySQL Query Optimizer Explained Through Optimizer Trace
The MySQL Query Optimizer Explained Through Optimizer Trace
 
Fast querying indexing for performance (4)
Fast querying   indexing for performance (4)Fast querying   indexing for performance (4)
Fast querying indexing for performance (4)
 
[Meetup] a successful migration from elastic search to clickhouse
[Meetup] a successful migration from elastic search to clickhouse[Meetup] a successful migration from elastic search to clickhouse
[Meetup] a successful migration from elastic search to clickhouse
 
MongoDB Performance Tuning
MongoDB Performance TuningMongoDB Performance Tuning
MongoDB Performance Tuning
 
MongoDB WiredTiger Internals
MongoDB WiredTiger InternalsMongoDB WiredTiger Internals
MongoDB WiredTiger Internals
 
MySQL Index Cookbook
MySQL Index CookbookMySQL Index Cookbook
MySQL Index Cookbook
 
Introduction to Redis
Introduction to RedisIntroduction to Redis
Introduction to Redis
 
ClickHouse Deep Dive, by Aleksei Milovidov
ClickHouse Deep Dive, by Aleksei MilovidovClickHouse Deep Dive, by Aleksei Milovidov
ClickHouse Deep Dive, by Aleksei Milovidov
 
A Fast Intro to Fast Query with ClickHouse, by Robert Hodges
A Fast Intro to Fast Query with ClickHouse, by Robert HodgesA Fast Intro to Fast Query with ClickHouse, by Robert Hodges
A Fast Intro to Fast Query with ClickHouse, by Robert Hodges
 
Indexing & Query Optimization
Indexing & Query OptimizationIndexing & Query Optimization
Indexing & Query Optimization
 
Streaming Operational Data with MariaDB MaxScale
Streaming Operational Data with MariaDB MaxScaleStreaming Operational Data with MariaDB MaxScale
Streaming Operational Data with MariaDB MaxScale
 
Introduction to Redis
Introduction to RedisIntroduction to Redis
Introduction to Redis
 
ProxySQL High Avalability and Configuration Management Overview
ProxySQL High Avalability and Configuration Management OverviewProxySQL High Avalability and Configuration Management Overview
ProxySQL High Avalability and Configuration Management Overview
 
PostgreSql query planning and tuning
PostgreSql query planning and tuningPostgreSql query planning and tuning
PostgreSql query planning and tuning
 
Histograms in MariaDB, MySQL and PostgreSQL
Histograms in MariaDB, MySQL and PostgreSQLHistograms in MariaDB, MySQL and PostgreSQL
Histograms in MariaDB, MySQL and PostgreSQL
 
MongoDB - Aggregation Pipeline
MongoDB - Aggregation PipelineMongoDB - Aggregation Pipeline
MongoDB - Aggregation Pipeline
 
Inside MongoDB: the Internals of an Open-Source Database
Inside MongoDB: the Internals of an Open-Source DatabaseInside MongoDB: the Internals of an Open-Source Database
Inside MongoDB: the Internals of an Open-Source Database
 
ReadConcern and WriteConcern
ReadConcern and WriteConcernReadConcern and WriteConcern
ReadConcern and WriteConcern
 
Reading the .explain() Output
Reading the .explain() OutputReading the .explain() Output
Reading the .explain() Output
 

Similar to MongoDB .local Toronto 2019: Tips and Tricks for Effective Indexing

MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDBMongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDBMongoDB
 
MongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDBMongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDBMongoDB
 
MongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDBMongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDBLisa Roth, PMP
 
MongoDB.local Austin 2018: Tips and Tricks for Avoiding Common Query Pitfalls
MongoDB.local Austin 2018: Tips and Tricks for Avoiding Common Query PitfallsMongoDB.local Austin 2018: Tips and Tricks for Avoiding Common Query Pitfalls
MongoDB.local Austin 2018: Tips and Tricks for Avoiding Common Query PitfallsMongoDB
 
MongoDB .local Bengaluru 2019: Tips and Tricks++ for Querying and Indexing Mo...
MongoDB .local Bengaluru 2019: Tips and Tricks++ for Querying and Indexing Mo...MongoDB .local Bengaluru 2019: Tips and Tricks++ for Querying and Indexing Mo...
MongoDB .local Bengaluru 2019: Tips and Tricks++ for Querying and Indexing Mo...MongoDB
 
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...MongoDB
 
Tips and Tricks for Avoiding Common Query Pitfalls
Tips and Tricks for Avoiding Common Query PitfallsTips and Tricks for Avoiding Common Query Pitfalls
Tips and Tricks for Avoiding Common Query PitfallsMongoDB
 
MongoDB.local Sydney 2019: Tips and Tricks for Avoiding Common Query Pitfalls
MongoDB.local Sydney 2019: Tips and Tricks for Avoiding Common Query PitfallsMongoDB.local Sydney 2019: Tips and Tricks for Avoiding Common Query Pitfalls
MongoDB.local Sydney 2019: Tips and Tricks for Avoiding Common Query PitfallsMongoDB
 
MongoDB.local Dallas 2019: Tips & Tricks for Avoiding Common Query Pitfalls
MongoDB.local Dallas 2019: Tips & Tricks for Avoiding Common Query PitfallsMongoDB.local Dallas 2019: Tips & Tricks for Avoiding Common Query Pitfalls
MongoDB.local Dallas 2019: Tips & Tricks for Avoiding Common Query PitfallsMongoDB
 
MongoDB World 2018: Tips and Tricks for Avoiding Common Query Pitfalls
MongoDB World 2018: Tips and Tricks for Avoiding Common Query PitfallsMongoDB World 2018: Tips and Tricks for Avoiding Common Query Pitfalls
MongoDB World 2018: Tips and Tricks for Avoiding Common Query PitfallsMongoDB
 
Tips and Tricks for Avoiding Common Query Pitfalls
Tips and Tricks for Avoiding Common Query PitfallsTips and Tricks for Avoiding Common Query Pitfalls
Tips and Tricks for Avoiding Common Query PitfallsMongoDB
 
Tips and Tricks for Avoiding Common Query Pitfalls Christian Kurze
Tips and Tricks for Avoiding Common Query Pitfalls Christian KurzeTips and Tricks for Avoiding Common Query Pitfalls Christian Kurze
Tips and Tricks for Avoiding Common Query Pitfalls Christian KurzeMongoDB
 
MongoDB.local Seattle 2019: Tips & Tricks for Avoiding Common Query Pitfalls
MongoDB.local Seattle 2019: Tips & Tricks for Avoiding Common Query PitfallsMongoDB.local Seattle 2019: Tips & Tricks for Avoiding Common Query Pitfalls
MongoDB.local Seattle 2019: Tips & Tricks for Avoiding Common Query PitfallsMongoDB
 
MongoDB .local Houston 2019:Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local Houston 2019:Tips and Tricks++ for Querying and Indexing MongoDBMongoDB .local Houston 2019:Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local Houston 2019:Tips and Tricks++ for Querying and Indexing MongoDBMongoDB
 
Fazendo mágica com ElasticSearch
Fazendo mágica com ElasticSearchFazendo mágica com ElasticSearch
Fazendo mágica com ElasticSearchPedro Franceschi
 
MongoDB .local Paris 2020: Tout savoir sur le moteur de recherche Full Text S...
MongoDB .local Paris 2020: Tout savoir sur le moteur de recherche Full Text S...MongoDB .local Paris 2020: Tout savoir sur le moteur de recherche Full Text S...
MongoDB .local Paris 2020: Tout savoir sur le moteur de recherche Full Text S...MongoDB
 
MongoDB .local Chicago 2019: Still Haven't Found What You Are Looking For? Us...
MongoDB .local Chicago 2019: Still Haven't Found What You Are Looking For? Us...MongoDB .local Chicago 2019: Still Haven't Found What You Are Looking For? Us...
MongoDB .local Chicago 2019: Still Haven't Found What You Are Looking For? Us...MongoDB
 
Mongo db mug_2012-02-07
Mongo db mug_2012-02-07Mongo db mug_2012-02-07
Mongo db mug_2012-02-07Will Button
 
CREATE INDEX … USING VODKA. VODKA CONNECTING INDEXES, Олег Бартунов, Александ...
CREATE INDEX … USING VODKA. VODKA CONNECTING INDEXES, Олег Бартунов, Александ...CREATE INDEX … USING VODKA. VODKA CONNECTING INDEXES, Олег Бартунов, Александ...
CREATE INDEX … USING VODKA. VODKA CONNECTING INDEXES, Олег Бартунов, Александ...Ontico
 

Similar to MongoDB .local Toronto 2019: Tips and Tricks for Effective Indexing (20)

MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDBMongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDB
 
MongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDBMongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDB
 
MongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDBMongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDB
 
MongoDB.local Austin 2018: Tips and Tricks for Avoiding Common Query Pitfalls
MongoDB.local Austin 2018: Tips and Tricks for Avoiding Common Query PitfallsMongoDB.local Austin 2018: Tips and Tricks for Avoiding Common Query Pitfalls
MongoDB.local Austin 2018: Tips and Tricks for Avoiding Common Query Pitfalls
 
MongoDB .local Bengaluru 2019: Tips and Tricks++ for Querying and Indexing Mo...
MongoDB .local Bengaluru 2019: Tips and Tricks++ for Querying and Indexing Mo...MongoDB .local Bengaluru 2019: Tips and Tricks++ for Querying and Indexing Mo...
MongoDB .local Bengaluru 2019: Tips and Tricks++ for Querying and Indexing Mo...
 
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
MongoDB .local San Francisco 2020: Tips and Tricks++ for Querying and Indexin...
 
Tips and Tricks for Avoiding Common Query Pitfalls
Tips and Tricks for Avoiding Common Query PitfallsTips and Tricks for Avoiding Common Query Pitfalls
Tips and Tricks for Avoiding Common Query Pitfalls
 
MongoDB.local Sydney 2019: Tips and Tricks for Avoiding Common Query Pitfalls
MongoDB.local Sydney 2019: Tips and Tricks for Avoiding Common Query PitfallsMongoDB.local Sydney 2019: Tips and Tricks for Avoiding Common Query Pitfalls
MongoDB.local Sydney 2019: Tips and Tricks for Avoiding Common Query Pitfalls
 
Avoid Query Pitfalls
Avoid Query PitfallsAvoid Query Pitfalls
Avoid Query Pitfalls
 
MongoDB.local Dallas 2019: Tips & Tricks for Avoiding Common Query Pitfalls
MongoDB.local Dallas 2019: Tips & Tricks for Avoiding Common Query PitfallsMongoDB.local Dallas 2019: Tips & Tricks for Avoiding Common Query Pitfalls
MongoDB.local Dallas 2019: Tips & Tricks for Avoiding Common Query Pitfalls
 
MongoDB World 2018: Tips and Tricks for Avoiding Common Query Pitfalls
MongoDB World 2018: Tips and Tricks for Avoiding Common Query PitfallsMongoDB World 2018: Tips and Tricks for Avoiding Common Query Pitfalls
MongoDB World 2018: Tips and Tricks for Avoiding Common Query Pitfalls
 
Tips and Tricks for Avoiding Common Query Pitfalls
Tips and Tricks for Avoiding Common Query PitfallsTips and Tricks for Avoiding Common Query Pitfalls
Tips and Tricks for Avoiding Common Query Pitfalls
 
Tips and Tricks for Avoiding Common Query Pitfalls Christian Kurze
Tips and Tricks for Avoiding Common Query Pitfalls Christian KurzeTips and Tricks for Avoiding Common Query Pitfalls Christian Kurze
Tips and Tricks for Avoiding Common Query Pitfalls Christian Kurze
 
MongoDB.local Seattle 2019: Tips & Tricks for Avoiding Common Query Pitfalls
MongoDB.local Seattle 2019: Tips & Tricks for Avoiding Common Query PitfallsMongoDB.local Seattle 2019: Tips & Tricks for Avoiding Common Query Pitfalls
MongoDB.local Seattle 2019: Tips & Tricks for Avoiding Common Query Pitfalls
 
MongoDB .local Houston 2019:Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local Houston 2019:Tips and Tricks++ for Querying and Indexing MongoDBMongoDB .local Houston 2019:Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local Houston 2019:Tips and Tricks++ for Querying and Indexing MongoDB
 
Fazendo mágica com ElasticSearch
Fazendo mágica com ElasticSearchFazendo mágica com ElasticSearch
Fazendo mágica com ElasticSearch
 
MongoDB .local Paris 2020: Tout savoir sur le moteur de recherche Full Text S...
MongoDB .local Paris 2020: Tout savoir sur le moteur de recherche Full Text S...MongoDB .local Paris 2020: Tout savoir sur le moteur de recherche Full Text S...
MongoDB .local Paris 2020: Tout savoir sur le moteur de recherche Full Text S...
 
MongoDB .local Chicago 2019: Still Haven't Found What You Are Looking For? Us...
MongoDB .local Chicago 2019: Still Haven't Found What You Are Looking For? Us...MongoDB .local Chicago 2019: Still Haven't Found What You Are Looking For? Us...
MongoDB .local Chicago 2019: Still Haven't Found What You Are Looking For? Us...
 
Mongo db mug_2012-02-07
Mongo db mug_2012-02-07Mongo db mug_2012-02-07
Mongo db mug_2012-02-07
 
CREATE INDEX … USING VODKA. VODKA CONNECTING INDEXES, Олег Бартунов, Александ...
CREATE INDEX … USING VODKA. VODKA CONNECTING INDEXES, Олег Бартунов, Александ...CREATE INDEX … USING VODKA. VODKA CONNECTING INDEXES, Олег Бартунов, Александ...
CREATE INDEX … USING VODKA. VODKA CONNECTING INDEXES, Олег Бартунов, Александ...
 

More from MongoDB

MongoDB SoCal 2020: Migrate Anything* to MongoDB Atlas
MongoDB SoCal 2020: Migrate Anything* to MongoDB AtlasMongoDB SoCal 2020: Migrate Anything* to MongoDB Atlas
MongoDB SoCal 2020: Migrate Anything* to MongoDB AtlasMongoDB
 
MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!
MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!
MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!MongoDB
 
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...MongoDB
 
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDB
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDBMongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDB
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDBMongoDB
 
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...MongoDB
 
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series DataMongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series DataMongoDB
 
MongoDB SoCal 2020: MongoDB Atlas Jump Start
 MongoDB SoCal 2020: MongoDB Atlas Jump Start MongoDB SoCal 2020: MongoDB Atlas Jump Start
MongoDB SoCal 2020: MongoDB Atlas Jump StartMongoDB
 
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]MongoDB
 
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2MongoDB
 
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...MongoDB
 
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!MongoDB
 
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your Mindset
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your MindsetMongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your Mindset
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your MindsetMongoDB
 
MongoDB .local San Francisco 2020: MongoDB Atlas Jumpstart
MongoDB .local San Francisco 2020: MongoDB Atlas JumpstartMongoDB .local San Francisco 2020: MongoDB Atlas Jumpstart
MongoDB .local San Francisco 2020: MongoDB Atlas JumpstartMongoDB
 
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++MongoDB
 
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...MongoDB
 
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep Dive
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep DiveMongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep Dive
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep DiveMongoDB
 
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & Golang
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & GolangMongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & Golang
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & GolangMongoDB
 
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...MongoDB
 
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...MongoDB
 
MongoDB .local Paris 2020: Les bonnes pratiques pour sécuriser MongoDB
MongoDB .local Paris 2020: Les bonnes pratiques pour sécuriser MongoDBMongoDB .local Paris 2020: Les bonnes pratiques pour sécuriser MongoDB
MongoDB .local Paris 2020: Les bonnes pratiques pour sécuriser MongoDBMongoDB
 

More from MongoDB (20)

MongoDB SoCal 2020: Migrate Anything* to MongoDB Atlas
MongoDB SoCal 2020: Migrate Anything* to MongoDB AtlasMongoDB SoCal 2020: Migrate Anything* to MongoDB Atlas
MongoDB SoCal 2020: Migrate Anything* to MongoDB Atlas
 
MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!
MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!
MongoDB SoCal 2020: Go on a Data Safari with MongoDB Charts!
 
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...
MongoDB SoCal 2020: Using MongoDB Services in Kubernetes: Any Platform, Devel...
 
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDB
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDBMongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDB
MongoDB SoCal 2020: A Complete Methodology of Data Modeling for MongoDB
 
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...
MongoDB SoCal 2020: From Pharmacist to Analyst: Leveraging MongoDB for Real-T...
 
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series DataMongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
MongoDB SoCal 2020: Best Practices for Working with IoT and Time-series Data
 
MongoDB SoCal 2020: MongoDB Atlas Jump Start
 MongoDB SoCal 2020: MongoDB Atlas Jump Start MongoDB SoCal 2020: MongoDB Atlas Jump Start
MongoDB SoCal 2020: MongoDB Atlas Jump Start
 
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]
MongoDB .local San Francisco 2020: Powering the new age data demands [Infosys]
 
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2
MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2
 
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...
MongoDB .local San Francisco 2020: Using MongoDB Services in Kubernetes: any ...
 
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!
MongoDB .local San Francisco 2020: Go on a Data Safari with MongoDB Charts!
 
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your Mindset
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your MindsetMongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your Mindset
MongoDB .local San Francisco 2020: From SQL to NoSQL -- Changing Your Mindset
 
MongoDB .local San Francisco 2020: MongoDB Atlas Jumpstart
MongoDB .local San Francisco 2020: MongoDB Atlas JumpstartMongoDB .local San Francisco 2020: MongoDB Atlas Jumpstart
MongoDB .local San Francisco 2020: MongoDB Atlas Jumpstart
 
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
MongoDB .local San Francisco 2020: Aggregation Pipeline Power++
 
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...
MongoDB .local San Francisco 2020: A Complete Methodology of Data Modeling fo...
 
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep Dive
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep DiveMongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep Dive
MongoDB .local San Francisco 2020: MongoDB Atlas Data Lake Technical Deep Dive
 
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & Golang
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & GolangMongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & Golang
MongoDB .local San Francisco 2020: Developing Alexa Skills with MongoDB & Golang
 
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...
MongoDB .local Paris 2020: Realm : l'ingrédient secret pour de meilleures app...
 
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...
MongoDB .local Paris 2020: Upply @MongoDB : Upply : Quand le Machine Learning...
 
MongoDB .local Paris 2020: Les bonnes pratiques pour sécuriser MongoDB
MongoDB .local Paris 2020: Les bonnes pratiques pour sécuriser MongoDBMongoDB .local Paris 2020: Les bonnes pratiques pour sécuriser MongoDB
MongoDB .local Paris 2020: Les bonnes pratiques pour sécuriser MongoDB
 

Recently uploaded

The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...itnewsafrica
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesBernd Ruecker
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructureitnewsafrica
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Kaya Weers
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integrationmarketing932765
 

Recently uploaded (20)

The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architectures
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
 

MongoDB .local Toronto 2019: Tips and Tricks for Effective Indexing

  • 1. @ #MDBlocal Tips and Tricks for Effective Indexing Alex Bevilacqua Technical Services Engineer alexbevi TORONTO
  • 2. #MDBLocal • Your data should be accessible … quickly • When applied properly, indexes can improve performance as if by … WHY DOES THIS MATTER?
  • 3. #MDBLocal • Working hard can suck and we all want to do less when possible • This goes for our database as well • The less index keys scanned or documents fetched from disk or cache … the better! • Let’s learn how to improve our indexes, TOGETHER! WHY DOES THIS MATTER?
  • 4. #MDBLocal IT’S ME … MARIO! ALEX! • Application Developer • Development Lead • System Architect • Technical Services Engineer • Author • MongoDB Fanboy
  • 6. #MDBLocal Alex Bevilacqua Technical Services Engineer Toronto I think I found some slow queries that may be missing indexes. What should I know?
  • 8. #MDBLocal Roadmap E-S-R Overview Guidelines: • Eà R • Eà S • Sà R E-S-R Considerations Operator Type Checks Consecutive Index Keys Exceptions?
  • 9. #MDBLocal Roadmap E-S-R Overview Guidelines: • Eà R • Eà S • Sà R E-S-R Considerations Operator Type Checks Consecutive Index Keys Exceptions?
  • 10. #MDBLocal E-S-R The ordering of index keys in a compound index is critically important.
  • 11. #MDBLocal E-S-R The ordering of index keys in a compound index is critically important. WHY?
  • 12. #MDBLocal E-S-R The ordering of index keys in a compound index is critically important. E-S-R provides guidance that is useful in most cases: • Equality first • Sort next • Range last
  • 13. #MDBLocal E-S-R The ordering of index keys in a compound index is critically important. E-S-R provides guidance that is useful in most cases: • Equality first • Sort next • Range last Nope, I don’t get it. Equality? Range? ….. Explain!
  • 14. #MDBLocal Definitions Equality Fields An exact match on a single value. For example: • {x:123} • {x:{$eq:123}} • {"x.y":123} Bounds: "[123.0, 123.0]"
  • 15. #MDBLocal Definitions Equality Fields Sort The (entire) requested sort. .sort({a:1, b:-1}) Bounds: "[MinKey, MaxKey]", "[MinKey, MaxKey]" An exact match on a single value. For example: • {x:123} • {x:{$eq:123}} • {"x.y":123} Bounds: "[123.0, 123.0]"
  • 16. #MDBLocal Definitions Equality Fields Sort Range Predicates Any predicates that are not exact matches. Some operators include: • {z:{$gt:9000}} • {z:{$lte:1000}} Bounds: "[9000.0, inf.0]", "[-inf.0, 1000.0]" The (entire) requested sort. .sort({a:1, b:-1}) Bounds: "[MinKey, MaxKey]", "[MinKey, MaxKey]" An exact match on a single value. For example: • {x:123} • {x:{$eq:123}} • {"x.y":123} Bounds: "[123.0, 123.0]"
  • 17. #MDBLocal Roadmap E-S-R Overview Guidelines: • Eà R • Eà S • Sà R E-S-R Considerations Operator Type Checks Consecutive Index Keys Exceptions?
  • 18. #MDBLocal Equality Equality keys are placed first in any order If present in the query shape, equality fields should always form the prefix for the index.
  • 19. #MDBLocal Equality Equality keys are placed first in any order If present in the query shape, equality fields should always form the prefix for the index. WHY?
  • 20. #MDBLocal Equality Equality keys are placed first in any order If present in the query shape, equality fields should always form the prefix for the index. db.games.find( {gamertag: "Ace", score: {$gt: 9000}} )
  • 21. #MDBLocal Equality db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) If present in the query shape, equality fields should always form the prefix for the index. Equality keys are placed first in any order
  • 22. #MDBLocal db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) Equality {gamertag: "Ace", score: 100} {gamertag: "Ace", score: 99,999} {gamertag: "Bob", score: 15,000} {gamertag: "Bob", score: 50,000}
  • 23. #MDBLocal db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {}{} 100 15,000 50,000 99,999 Ace Bob Bob Ace {gamertag: "Ace", score: 100} {gamertag: "Ace", score: 99,999} {gamertag: "Bob", score: 15,000} {gamertag: "Bob", score: 50,000} Equality
  • 24. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Bob Ace db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {} Equality "indexBounds" : { "score" : [ "(9000.0, inf.0]" ], "gamertag" : [ "["Ace", "Ace"]" ] } db.games.createIndex({score:1, gamertag:1})
  • 25. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Bob Ace db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {} Equality "indexBounds" : { "score" : [ "(9000.0, inf.0]" ], "gamertag" : [ "["Ace", "Ace"]" ] } gamertag db.games.createIndex({score:1, gamertag:1})
  • 26. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Bob Ace db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {} Equality "indexBounds" : { "score" : [ "(9000.0, inf.0]" ], "gamertag" : [ "["Ace", "Ace"]" ] } gamertag score db.games.createIndex({score:1, gamertag:1})
  • 27. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Bob Ace db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {} Equality "indexBounds" : { "score" : [ "(9000.0, inf.0]" ], "gamertag" : [ "["Ace", "Ace"]" ] } gamertag score db.games.createIndex({score:1, gamertag:1})
  • 28. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Bob Ace db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {} Equality "indexBounds" : { "score" : [ "(9000.0, inf.0]" ], "gamertag" : [ "["Ace", "Ace"]" ] } gamertag score db.games.createIndex({score:1, gamertag:1})
  • 29. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Bob Ace db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {} Equality "indexBounds" : { "score" : [ "(9000.0, inf.0]" ], "gamertag" : [ "["Ace", "Ace"]" ] } gamertag score db.games.createIndex({score:1, gamertag:1})
  • 30. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Bob Ace db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {} Equality "indexBounds" : { "score" : [ "(9000.0, inf.0]" ], "gamertag" : [ "["Ace", "Ace"]" ] } gamertag score db.games.createIndex({score:1, gamertag:1})
  • 31. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Bob Ace db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {} Equality "indexBounds" : { "score" : [ "(9000.0, inf.0]" ], "gamertag" : [ "["Ace", "Ace"]" ] } gamertag score db.games.createIndex({score:1, gamertag:1})
  • 32. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Bob Ace db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {} Equality "indexBounds" : { "score" : [ "(9000.0, inf.0]" ], "gamertag" : [ "["Ace", "Ace"]" ] } gamertag score db.games.createIndex({score:1, gamertag:1})
  • 33. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Bob Ace db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {} Equality "indexBounds" : { "score" : [ "(9000.0, inf.0]" ], "gamertag" : [ "["Ace", "Ace"]" ] } gamertag score db.games.createIndex({score:1, gamertag:1})
  • 34. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Bob Ace db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {} Equality
  • 35. #MDBLocal Ace Bob Bob Ace db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) 100 99,999 15,000 50,000 {} {} {} {} Equality
  • 36. #MDBLocal 100 Ace Bob 99,999 15,000 50,000 db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {} Equality "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "score" : [ "(9000.0, inf.0]" ], } db.games.createIndex({gamertag:1, score:1})
  • 37. #MDBLocal 100 Ace Bob 99,999 15,000 50,000 db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {} Equality "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "score" : [ "(9000.0, inf.0]" ], } gamertag db.games.createIndex({gamertag:1, score:1})
  • 38. #MDBLocal 100 Ace Bob 99,999 15,000 50,000 db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {} Equality "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "score" : [ "(9000.0, inf.0]" ], } gamertag score db.games.createIndex({gamertag:1, score:1})
  • 39. #MDBLocal 100 Ace Bob 99,999 15,000 50,000 db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {} Equality "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "score" : [ "(9000.0, inf.0]" ], } gamertag score db.games.createIndex({gamertag:1, score:1})
  • 40. #MDBLocal 100 Ace Bob 99,999 15,000 50,000 db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {} Equality "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "score" : [ "(9000.0, inf.0]" ], } gamertag score db.games.createIndex({gamertag:1, score:1})
  • 41. #MDBLocal 100 Ace Bob 99,999 15,000 50,000 db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) {} {} {} {} Equality "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "score" : [ "(9000.0, inf.0]" ], } gamertag score db.games.createIndex({gamertag:1, score:1})
  • 42. #MDBLocal db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) R E R E Equality before Range
  • 43. #MDBLocal Roadmap E-S-R Overview Guidelines: • Eà R • Eà S • Sà R E-S-R Considerations Operator Type Checks Consecutive Index Keys Exceptions?
  • 44. #MDBLocal Sort fields are placed next Placing sort predicates after sequential equality keys allow for the index to: Provide a non-blocking sort. Minimize the amount of scanning required. db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) Sort
  • 45. #MDBLocal db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) Sort 100 15,000 50,000 99,999 Ace Bob Bob Acegamertag score db.games.createIndex({score:1, gamertag:1})
  • 46. #MDBLocal db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) Sort 100 15,000 50,000 99,999 Ace Bob Bob Ace {} {} {} {} gamertag score db.games.createIndex({score:1, gamertag:1})
  • 47. #MDBLocal db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) Sort 100 15,000 50,000 99,999 Ace Bob Bob Ace {} {} {} {} gamertag score db.games.createIndex({score:1, gamertag:1})
  • 48. #MDBLocal db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) Sort 100 15,000 50,000 99,999 Ace Bob Bob Ace {1} {} {} {2} gamertag score db.games.createIndex({score:1, gamertag:1})
  • 49. #MDBLocal db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) Sort 100 15,000 50,000 99,999 Ace Bob Bob Ace {1} {} {} {2} gamertag score "indexBounds" : { "score" : [ "[MinKey, MaxKey]" ], "gamertag" : [ "["Ace", "Ace"]" ] } db.games.createIndex({score:1, gamertag:1})
  • 50. #MDBLocal db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) Sort 100 15,000 50,000 99,999 Ace Bob Bob Ace {1} {} {} {2} gamertag score "indexBounds" : { "score" : [ "[MinKey, MaxKey]" ], "gamertag" : [ "["Ace", "Ace"]" ] } db.games.createIndex({score:1, gamertag:1})
  • 51. #MDBLocal db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) Sort 100 15,000 50,000 99,999 Ace Bob Bob Ace {1} {} {} {2} gamertag score "indexBounds" : { "score" : [ "[MinKey, MaxKey]" ], "gamertag" : [ "["Ace", "Ace"]” ] } db.games.createIndex({score:1, gamertag:1})
  • 52. #MDBLocal db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) Sort 100 15,000 50,000 99,999 Ace Bob Bob Ace {1} {} {} {2} gamertag score "indexBounds" : { "score" : [ "[MinKey, MaxKey]" ], "gamertag" : [ "["Ace", "Ace"]” ] } db.games.createIndex({score:1, gamertag:1})
  • 53. #MDBLocal db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) Sort 100 15,000 50,000 99,999 Ace Bob Bob Ace {1} {} {} {2} gamertag score "indexBounds" : { "score" : [ "[MinKey, MaxKey]" ], "gamertag" : [ "["Ace", "Ace"]” ] } db.games.createIndex({score:1, gamertag:1})
  • 54. #MDBLocal Sort 100 15,000 50,000 99,999 Ace Bob Bob Ace {1} {} {} {2} db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) gamertag score "indexBounds" : { "score" : [ "[MinKey, MaxKey]" ], "gamertag" : [ "["Ace", "Ace"]” ] } db.games.createIndex({score:1, gamertag:1})
  • 55. #MDBLocal Sort 100 15,000 50,000 99,999 Ace Bob Bob Ace {1} {} {} {2} db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) gamertag score "indexBounds" : { "score" : [ "[MinKey, MaxKey]" ], "gamertag" : [ "["Ace", "Ace"]” ] } db.games.createIndex({score:1, gamertag:1})
  • 56. #MDBLocal Sort 100 15,000 50,000 99,999 Ace Bob Bob Ace {1} {} {} {2} db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) gamertag score "indexBounds" : { "score" : [ "[MinKey, MaxKey]" ], "gamertag" : [ "["Ace", "Ace"]” ] } db.games.createIndex({score:1, gamertag:1})
  • 57. #MDBLocal Sort 100 15,000 50,000 99,999 Ace Bob Bob Ace {1} {} {} {2} db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) gamertag score "indexBounds" : { "score" : [ "[MinKey, MaxKey]" ], "gamertag" : [ "["Ace", "Ace"]” ] } db.games.createIndex({score:1, gamertag:1})
  • 58. #MDBLocal Sort 100 15,000 50,000 99,999 Ace Bob Bob Ace {1} {} {} {2} db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) gamertag score "indexBounds" : { "score" : [ "[MinKey, MaxKey]" ], "gamertag" : [ "["Ace", "Ace"]” ] } db.games.createIndex({score:1, gamertag:1})
  • 59. #MDBLocal Sort 100 15,000 50,000 99,999 Ace Bob Bob Ace {1} {} {} {2} db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) gamertag score "indexBounds" : { "score" : [ "[MinKey, MaxKey]" ], "gamertag" : [ "["Ace", "Ace"]” ] } db.games.createIndex({score:1, gamertag:1})
  • 60. #MDBLocal Sort 100 15,000 50,000 99,999 Ace Bob Bob Ace {1} {} {} {2} db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) gamertag score "indexBounds" : { "score" : [ "[MinKey, MaxKey]" ], "gamertag" : [ "["Ace", "Ace"]” ] } db.games.createIndex({score:1, gamertag:1})
  • 61. #MDBLocal Sort 100 15,000 50,000 99,999 Ace Bob Bob Ace {1} {} {} {2} db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
  • 62. #MDBLocal Sort Ace Bob Bob Ace 100 99,999 15,000 50,000 {1} {2} {} {} db.games.find( {gamertag: "Ace"} ).sort( {score: 1} )
  • 63. #MDBLocal Sort 100 Ace Bob 99,999 15,000 50,000 {}{1} {2} {} db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) gamertag score "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], ”score" : [ "[MinKey, MaxKey]" ] } db.games.createIndex({gamertag:1, score:1})
  • 64. #MDBLocal Sort 100 Ace Bob 99,999 15,000 50,000 {}{1} {2} {} db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) gamertag score "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], ”score" : [ "[MinKey, MaxKey]" ] } db.games.createIndex({gamertag:1, score:1})
  • 65. #MDBLocal Sort 100 Ace Bob 99,999 15,000 50,000 {}{1} {2} {} db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) gamertag score "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], ”score" : [ "[MinKey, MaxKey]" ] } db.games.createIndex({gamertag:1, score:1})
  • 66. #MDBLocal Sort 100 Ace Bob 99,999 15,000 50,000 {}{1} {2} {} db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) gamertag score "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], ”score" : [ "[MinKey, MaxKey]" ] } db.games.createIndex({gamertag:1, score:1})
  • 67. #MDBLocal Sort 100 Ace Bob 99,999 15,000 50,000 {}{1} {2} {} db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) gamertag score "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], ”score" : [ "[MinKey, MaxKey]" ] } db.games.createIndex({gamertag:1, score:1})
  • 68. #MDBLocal Sort 100 Ace Bob 99,999 15,000 50,000 {}{1} {2} {} db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) gamertag score "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], ”score" : [ "[MinKey, MaxKey]" ] } db.games.createIndex({gamertag:1, score:1})
  • 69. #MDBLocal Sort 100 Ace Bob 99,999 15,000 50,000 {}{1} {2} {} db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) gamertag score "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], ”score" : [ "[MinKey, MaxKey]" ] } db.games.createIndex({gamertag:1, score:1})
  • 70. #MDBLocal Sort after Equality S E S E db.games.find( {gamertag: "Ace"} ).sort( {score: 1} ) Don’t do this, it may require a full index scan
  • 71. #MDBLocal Roadmap E-S-R Overview Guidelines: • Eà R • Eà S • Sà R E-S-R Considerations Operator Type Checks Consecutive Index Keys Exceptions?
  • 72. #MDBLocal Range fields are usually last This allows them to: Still participate in filtering the data But does not force a blocking sort. db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) Range
  • 73. #MDBLocal db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) R E R E Range after Equality
  • 74. #MDBLocal db.games.find( {gamertag: "Ace", score: {$gt: 9000}} ) R E R E Range after Equality Should range come after sort too?
  • 75. #MDBLocal R E R E Range after Equality db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Should range come after sort too?
  • 76. #MDBLocal R E R E Range db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1})
  • 77. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Bob Ace * db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range gamertag score db.games.createIndex({ …, score:1, gamertag:1})
  • 78. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Bob Ace * db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range gamertag score db.games.createIndex({ …, score:1, gamertag:1})
  • 79. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Cali Ace * db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range gamertag score db.games.createIndex({ …, score:1, gamertag:1})
  • 80. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Cali Ace * db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range {} {} {} {}{1}{2} {3} gamertag score db.games.createIndex({ …, score:1, gamertag:1})
  • 81. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Cali Ace * {} {2} {3} {1} db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range gamertag score "indexBounds" : { *, "score" : [ "(9000.0, inf.0]" ], "gamertag" : [ "[MinKey, MaxKey]" ] } db.games.createIndex({ …, score:1, gamertag:1})
  • 82. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Cali Ace * {} {2} {3} {1} db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range gamertag score "indexBounds" : { *, "score" : [ "(9000.0, inf.0]" ], "gamertag" : [ "[MinKey, MaxKey]" ] } db.games.createIndex({ …, score:1, gamertag:1})
  • 83. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Cali Ace * {} {2} {3} {1} db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range gamertag score "indexBounds" : { *, "score" : [ "(9000.0, inf.0]" ], "gamertag" : [ "[MinKey, MaxKey]" ] } db.games.createIndex({ …, score:1, gamertag:1})
  • 84. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Cali Ace * {} {2} {3} {1} db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range gamertag score "indexBounds" : { *, "score" : [ "(9000.0, inf.0]" ], "gamertag" : [ "[MinKey, MaxKey]" ] } db.games.createIndex({ …, score:1, gamertag:1})
  • 85. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Cali Ace * {} {2} {3} {1} db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range gamertag score "indexBounds" : { *, "score" : [ "(9000.0, inf.0]" ], "gamertag" : [ "[MinKey, MaxKey]" ] } db.games.createIndex({ …, score:1, gamertag:1})
  • 86. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Cali Ace * {} {2} {3} {1} db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range gamertag score "indexBounds" : { *, "score" : [ "(9000.0, inf.0]" ], "gamertag" : [ "[MinKey, MaxKey]" ] } db.games.createIndex({ …, score:1, gamertag:1})
  • 87. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Cali Ace * {} {2} {3} {1} db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range gamertag score "indexBounds" : { *, "score" : [ "(9000.0, inf.0]" ], "gamertag" : [ "[MinKey, MaxKey]" ] } db.games.createIndex({ …, score:1, gamertag:1})
  • 88. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Cali Ace * {} {2} {3} {1} db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range gamertag score "indexBounds" : { *, "score" : [ "(9000.0, inf.0]" ], "gamertag" : [ "[MinKey, MaxKey]" ] } db.games.createIndex({ …, score:1, gamertag:1})
  • 89. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Cali Ace * {} {2} {3} {1} db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range gamertag score "indexBounds" : { *, "score" : [ "(9000.0, inf.0]" ], "gamertag" : [ "[MinKey, MaxKey]" ] } db.games.createIndex({ …, score:1, gamertag:1})
  • 90. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Cali Ace * {} {2} {3} {1} db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range gamertag score "indexBounds" : { *, "score" : [ "(9000.0, inf.0]" ], "gamertag" : [ "[MinKey, MaxKey]" ] } db.games.createIndex({ …, score:1, gamertag:1})
  • 91. #MDBLocal {2} {3} {1} db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range Blocking SortBlocking Sort BS
  • 92. #MDBLocal {2}{3}{1} db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range BS
  • 93. #MDBLocal 100 15,000 50,000 99,999 Ace Bob Cali Ace * {} {2} {3} {1} db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range
  • 94. #MDBLocal db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range * Ace Bob Cali Ace 100 15,000 50,00099,999 {} {1} {2} {3}
  • 95. #MDBLocal * 100 15,000 50,00099,999 Ace Bob Cali db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range {} {1} {3} score gamertag "indexBounds" : { *, "gamertag" : [ "[MinKey, MaxKey]" ] "score" : [ "(9000.0, inf.0]" ] } db.games.createIndex({ …, gamertag:1, score:1}) {2}
  • 96. #MDBLocal * 100 15,000 50,00099,999 Ace Bob Cali db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range {} {1} {3} score gamertag "indexBounds" : { *, "gamertag" : [ "[MinKey, MaxKey]" ] "score" : [ "(9000.0, inf.0]" ] } db.games.createIndex({ …, gamertag:1, score:1}) {2}
  • 97. #MDBLocal * 100 15,000 50,00099,999 Ace Bob Cali db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range {} {1} {3} score gamertag "indexBounds" : { *, "gamertag" : [ "[MinKey, MaxKey]" ] "score" : [ "(9000.0, inf.0]" ] } db.games.createIndex({ …, gamertag:1, score:1}) {2}
  • 98. #MDBLocal * 100 15,000 50,00099,999 Ace Bob Cali db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range {} {1} {3} score gamertag "indexBounds" : { *, "gamertag" : [ "[MinKey, MaxKey]" ] "score" : [ "(9000.0, inf.0]" ] } db.games.createIndex({ …, gamertag:1, score:1}) {2}
  • 99. #MDBLocal * 100 15,000 50,00099,999 Ace Bob Cali db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range {} {1} {3} score gamertag "indexBounds" : { *, "gamertag" : [ "[MinKey, MaxKey]" ] "score" : [ "(9000.0, inf.0]" ] } db.games.createIndex({ …, gamertag:1, score:1}) {2}
  • 100. #MDBLocal * 100 15,000 50,00099,999 Ace Bob Cali db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range {} {1} {3} score gamertag "indexBounds" : { *, "gamertag" : [ "[MinKey, MaxKey]" ] "score" : [ "(9000.0, inf.0]" ] } db.games.createIndex({ …, gamertag:1, score:1}) {2}
  • 101. #MDBLocal * 100 15,000 50,00099,999 Ace Bob Cali db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range {} {1} {3} score gamertag "indexBounds" : { *, "gamertag" : [ "[MinKey, MaxKey]" ] "score" : [ "(9000.0, inf.0]" ] } db.games.createIndex({ …, gamertag:1, score:1}) {2}
  • 102. #MDBLocal * 100 15,000 50,00099,999 Ace Bob Cali db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range {} {1} {3} score gamertag "indexBounds" : { *, "gamertag" : [ "[MinKey, MaxKey]" ] "score" : [ "(9000.0, inf.0]" ] } db.games.createIndex({ …, gamertag:1, score:1}) {2}
  • 103. #MDBLocal * 100 15,000 50,00099,999 Ace Bob Cali db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range {} {1} {3} score gamertag "indexBounds" : { *, "gamertag" : [ "[MinKey, MaxKey]" ] "score" : [ "(9000.0, inf.0]" ] } db.games.createIndex({ …, gamertag:1, score:1}) {2}
  • 104. #MDBLocal * 100 15,000 50,00099,999 Ace Bob Cali db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range {} {1} {3} score gamertag "indexBounds" : { *, "gamertag" : [ "[MinKey, MaxKey]" ] "score" : [ "(9000.0, inf.0]" ] } db.games.createIndex({ …, gamertag:1, score:1}) {2}
  • 105. #MDBLocal * 100 15,000 50,00099,999 Ace Bob Cali db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range {} {1} {3} score gamertag "indexBounds" : { *, "gamertag" : [ "[MinKey, MaxKey]" ] "score" : [ "(9000.0, inf.0]" ] } db.games.createIndex({ …, gamertag:1, score:1}) {2}
  • 106. #MDBLocal BS R S R S db.games.find({*, score: {$gt: 9000}}).sort({gamertag: 1}) Range after Sort
  • 107. #MDBLocal Roadmap E-S-R Overview Guidelines: • Eà R • Eà S • Sà R E-S-R Considerations Operator Type Checks Consecutive Index Keys Exceptions?
  • 108. #MDBLocal Operator Type Check Some operators are simple $eq: Equality $gte: Range Others are trickier
  • 109. #MDBLocal Operator Type Check - Inequality Inequality Operators: E, S, or R? • $ne:123 • $nin:[1,2] Range!
  • 110. #MDBLocal Operator Type Check - Inequality Inequality Operators: E, S, or R? • $ne:123 • $nin:[1,2] Range! But … how do you know?
  • 111. #MDBLocal Operator Type Check - Inequality Inequality Operators: E, S, or R? • $ne:123 • $nin:[1,2] Range! "indexBounds" : { "x" : [ "[MinKey, 123.0)", "(123.0, MaxKey]" ] }
  • 112. #MDBLocal Operator Type Check - Inequality Range! "indexBounds" : { "x" : [ "[MinKey, 123.0)", "(123.0, MaxKey]" ] } 50 123 999
  • 113. #MDBLocal Operator Type Check - Inequality Range! "indexBounds" : { "x" : [ "[MinKey, 123.0)", "(123.0, MaxKey]" ] } 50 123 999
  • 114. #MDBLocal Operator Type Check - Inequality Range! "indexBounds" : { "x" : [ "[MinKey, 123.0)", "(123.0, MaxKey]" ] } 50 123 999
  • 115. #MDBLocal Operator Type Check - Regex Regex Operators: E, S, or R? • {str:/car/} • {str:/^car/i} Range!
  • 116. #MDBLocal Operator Type Check - Regex Regex Operators: E, S, or R? • {str:/car/} • {str:/^car/i} Range!
  • 117. #MDBLocal Operator Type Check - Regex Regex Operators: E, S, or R? • {str:/car/} • {str:/^car/i} Range! planecar racecar
  • 118. #MDBLocal Operator Type Check - Regex Regex Operators: E, S, or R? • {str:/car/} • {str:/^car/i} Range! planecar racecar
  • 119. #MDBLocal Operator Type Check - Regex Regex Operators: E, S, or R? • {str:/car/} • {str:/^car/i} Range! planecar racecar
  • 120. #MDBLocal Operator Type Check - Regex Regex Operators: E, S, or R? • {str:/car/} • {str:/^car/i} Range! p???ecar racecar
  • 121. #MDBLocal Operator Type Check - Regex Regex Operators: E, S, or R? • {str:/car/} • {str:/^car/i} Range! p???ecar racecar
  • 122. #MDBLocal Operator Type Check - Regex Regex Operators: E, S, or R? • {str:/car/} • {str:/^car/i} Range!
  • 123. #MDBLocal Operator Type Check - Regex Regex Operators: E, S, or R? • {str:/car/} • {str:/^car/i} Range! raincarry
  • 124. #MDBLocal Operator Type Check - Regex Regex Operators: E, S, or R? • {str:/car/} • {str:/^car/i} Range! raincarry
  • 125. #MDBLocal Operator Type Check - Regex Regex Operators: E, S, or R? • {str:/car/} • {str:/^car/i} Range! raincarry Carpool
  • 126. #MDBLocal Operator Type Check - Regex Regex Operators: E, S, or R? • {str:/car/} • {str:/^car/i} Range! raincarry Carpool
  • 127. #MDBLocal Operator Type Check - Regex Regex Operators: E, S, or R? • {str:/car/} • {str:/^car/i} Range! raincarry Carpool
  • 128. #MDBLocal Operator Type Check - Regex Regex Operators: E, S, or R? • {str:/car/} • {str:/^car/i} Range! raincarry Carpoo l Woah Woah WOAH …. Since the regex is left anchored, can’t we skip the middle tree?
  • 129. #MDBLocal Operator Type Check - Regex Regex Operators: E, S, or R? • {str:/car/} • {str:/^car/i} Range! raincarry Carpoo l Woah Woah WOAH …. Since the regex is left anchored, can’t we skip the middle tree?
  • 130. #MDBLocal Operator Type Check - Regex Regex Operators: E, S, or R? • {str:/car/} • {str:/^car/i} Range! cArrycarry Carpoo l Woah Woah WOAH …. Since the regex is left anchored, can’t we skip the middle tree?
  • 131. #MDBLocal Operator Type Check - Regex Regex Operators: E, S, or R? • {str:/car/} • {str:/^car/i} Range! cArrycarry Carpoo l Woah Woah WOAH …. Since the regex is left anchored, can’t we skip the middle tree?
  • 132. #MDBLocal Operator Type Check - Regex Regex Operators: E, S, or R? • {str:/car/} • {str:/^car/i} Range! cArrycarry Carpoo l
  • 133. #MDBLocal Operator Type Check - $in $in filters: E, S, or R? • {field:{$in:[1,3]}} … it depends with respect to key ordering Alone: a series of Equality matches Combined: possibly a Range
  • 134. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}})
  • 135. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}) "indexBounds" : { "field" : [ "[1.0, 1.0]", "[3.0, 3.0]" ] } ? 1 2 3 C G B F A D db.coll.createIndex({field:1, sortField:1})
  • 136. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}) "indexBounds" : { "field" : [ "[1.0, 1.0]", "[3.0, 3.0]" ] } ? 1 2 3 C G B F A D db.coll.createIndex({field:1, sortField:1})
  • 137. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}) "indexBounds" : { "field" : [ "[1.0, 1.0]", "[3.0, 3.0]" ] } ? 1 2 3 C G B F A D db.coll.createIndex({field:1, sortField:1})
  • 138. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}) "indexBounds" : { "field" : [ "[1.0, 1.0]", "[3.0, 3.0]" ] } ? 1 2 3 C G B F A D db.coll.createIndex({field:1, sortField:1})
  • 139. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}) "indexBounds" : { "field" : [ "[1.0, 1.0]", "[3.0, 3.0]" ] } ? 1 2 3 C G B F A D db.coll.createIndex({field:1, sortField:1})
  • 140. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}) "indexBounds" : { "field" : [ "[1.0, 1.0]", "[3.0, 3.0]" ] } ? 1 2 3 C G B F A D db.coll.createIndex({field:1, sortField:1})
  • 141. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}) .sort({sortField:1}) "indexBounds" : { "field" : [ "[1.0, 1.0]", "[3.0, 3.0]" ] } ? 1 2 3 C G B F A D db.coll.createIndex({field:1, sortField:1})
  • 142. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}) .sort({sortField:1}) "indexBounds" : { "field" : [ "[1.0, 1.0]", "[3.0, 3.0]" ], "sortField" : [ "[MinKey, MaxKey]" ] } ? 1 2 3 C G B F A D db.coll.createIndex({field:1, sortField:1})
  • 143. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}) .sort({sortField:1}) "indexBounds" : { "field" : [ "[1.0, 1.0]", "[3.0, 3.0]" ], "sortField" : [ "[MinKey, MaxKey]" ] } ? 1 2 3 C G B F A D db.coll.createIndex({field:1, sortField:1})
  • 144. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}) .sort({sortField:1}) "indexBounds" : { "field" : [ "[1.0, 1.0]", "[3.0, 3.0]" ], "sortField" : [ "[MinKey, MaxKey]" ] } ? 1 2 3 C G B F A D db.coll.createIndex({field:1, sortField:1})
  • 145. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}) .sort({sortField:1}) "indexBounds" : { "field" : [ "[1.0, 1.0]", "[3.0, 3.0]" ], "sortField" : [ "[MinKey, MaxKey]" ] } ? 1 2 3 C G B F A D db.coll.createIndex({field:1, sortField:1})
  • 146. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}) .sort({sortField:1}) "indexBounds" : { "field" : [ "[1.0, 1.0]", "[3.0, 3.0]" ], "sortField" : [ "[MinKey, MaxKey]" ] } ? 1 2 3 C G B F A D BS db.coll.createIndex({field:1, sortField:1})
  • 147. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}) .sort({sortField:1}) "indexBounds" : { "field" : [ "[1.0, 1.0]", "[3.0, 3.0]" ], "sortField" : [ "[MinKey, MaxKey]" ] } ? 1 2 3 C G B F A D BS db.coll.createIndex({field:1, sortField:1})
  • 148. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}) .sort({sortField:1}) ? 1 2 3 C G B F A D db.coll.createIndex({field:1, sortField:1})
  • 149. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}).sort({sortField:1}) ? 1 2 3 C G B F A D db.coll.createIndex({field:1, sortField:1})
  • 150. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}).sort({sortField:1}) "indexBounds" : { "field" : [ "[1.0, 1.0]", ], "sortField" : [ "[MinKey, MaxKey]" ] } ? 1 2 3 C G B F A D db.coll.createIndex({field:1, sortField:1})
  • 151. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}).sort({sortField:1}) "indexBounds" : { "field" : [ "[1.0, 1.0]", ], "sortField" : [ "[MinKey, MaxKey]" ] } ? 1 2 3 C G B F A D db.coll.createIndex({field:1, sortField:1})
  • 152. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}).sort({sortField:1}) "indexBounds" : { "field" : [ "[1.0, 1.0]", ], "sortField" : [ "[MinKey, MaxKey]" ] } ? 1 2 3 C G B F A D db.coll.createIndex({field:1, sortField:1})
  • 153. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}).sort({sortField:1}) "indexBounds" : { "field" : [ "[1.0, 1.0]", ], "sortField" : [ "[MinKey, MaxKey]" ] } ? 1 2 3 C G B F A D db.coll.createIndex({field:1, sortField:1})
  • 154. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}).sort({sortField:1}) "indexBounds" : { "field" : [ "[1.0, 1.0]", ], "sortField" : [ "[MinKey, MaxKey]" ] } ? 1 2 3 C G B F A D db.coll.createIndex({field:1, sortField:1})
  • 155. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}).sort({sortField:1}) "indexBounds" : { "field" : [ "[1.0, 1.0]", ], "sortField" : [ "[MinKey, MaxKey]" ] } "indexBounds" : { "field" : [ "[3.0, 3.0]", ], "sortField" : [ "[MinKey, MaxKey]" ] } ? 1 2 3 C G B F A D db.coll.createIndex({field:1, sortField:1})
  • 156. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}).sort({sortField:1}) "indexBounds" : { "field" : [ "[1.0, 1.0]", ], "sortField" : [ "[MinKey, MaxKey]" ] } "indexBounds" : { "field" : [ "[3.0, 3.0]", ], "sortField" : [ "[MinKey, MaxKey]" ] } ? 1 2 3 C G B F A D ? 1 2 3 C G B F A D db.coll.createIndex({field:1, sortField:1})
  • 157. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}).sort({sortField:1}) "indexBounds" : { "field" : [ "[1.0, 1.0]", ], "sortField" : [ "[MinKey, MaxKey]" ] } "indexBounds" : { "field" : [ "[3.0, 3.0]", ], "sortField" : [ "[MinKey, MaxKey]" ] } ? 1 2 3 C G B F A D ? 1 2 3 C G B F A D db.coll.createIndex({field:1, sortField:1})
  • 158. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}).sort({sortField:1}) "indexBounds" : { "field" : [ "[1.0, 1.0]", ], "sortField" : [ "[MinKey, MaxKey]" ] } "indexBounds" : { "field" : [ "[3.0, 3.0]", ], "sortField" : [ "[MinKey, MaxKey]" ] } ? 1 2 3 C G B F A D ? 1 2 3 C G B F A D db.coll.createIndex({field:1, sortField:1})
  • 159. #MDBLocal Operator Type Check - $in .find({field:{$in:[1,3]}}).sort({sortField:1}) "indexBounds" : { "field" : [ "[1.0, 1.0]", ], "sortField" : [ "[MinKey, MaxKey]" ] } "indexBounds" : { "field" : [ "[3.0, 3.0]", ], "sortField" : [ "[MinKey, MaxKey]" ] } ? 1 2 3 C G B F A D ? 1 2 3 C G B F A D {2} {4} {1} {3} Sort Merge db.coll.createIndex({field:1, sortField:1})
  • 161. #MDBLocal Roadmap E-S-R Overview Guidelines: • Eà R • Eà S • Sà R E-S-R Considerations Operator Type Checks Consecutive Index Keys Exceptions?
  • 162. #MDBLocal Consecutive Index Keys Given Indexes: {gamertag:1, date:1, game:1} {gamertag:1, game:1, date:1} Which one is “better”? It depends on the query shape(s)! Consider the query: .find({ gamertag:"Ace", game: "Halo” })
  • 164. #MDBLocal Consecutive Index Keys Ace Mario Halo 2016 2017 Mario Halo 2018 2019 .find({ gamertag:"Ace", game: "Halo” }) db.games.createIndex({gamertag:1, date:1, game:1})
  • 165. #MDBLocal Consecutive Index Keys Ace Mario Halo 2016 2017 Mario Halo 2018 2019 .find({ gamertag:"Ace", game: "Halo” }) {} {} {} {} db.games.createIndex({gamertag:1, date:1, game:1})
  • 166. #MDBLocal Consecutive Index Keys Ace Mario Halo 2016 2017 Mario Halo 2018 2019 .find({ gamertag:"Ace", game: "Halo” }) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[MinKey, MaxKey]" ], "game" : [ "["Halo", "Halo"]" ] } {} {} {} {} db.games.createIndex({gamertag:1, date:1, game:1})
  • 167. #MDBLocal Consecutive Index Keys Ace Mario Halo 2016 2017 Mario Halo 2018 2019 .find({ gamertag:"Ace", game: "Halo” }) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[MinKey, MaxKey]" ], "game" : [ "["Halo", "Halo"]" ] } {} {} {} {} db.games.createIndex({gamertag:1, date:1, game:1})
  • 168. #MDBLocal Consecutive Index Keys Ace Mario Halo 2016 2017 Mario Halo 2018 2019 .find({ gamertag:"Ace", game: "Halo” }) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[MinKey, MaxKey]" ], "game" : [ "["Halo", "Halo"]" ] } {} {} {} {} db.games.createIndex({gamertag:1, date:1, game:1})
  • 169. #MDBLocal Consecutive Index Keys Ace Mario Halo 2016 2017 Mario Halo 2018 2019 .find({ gamertag:"Ace", game: "Halo” }) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[MinKey, MaxKey]" ], "game" : [ "["Halo", "Halo"]" ] } {} {} {} {} db.games.createIndex({gamertag:1, date:1, game:1})
  • 170. #MDBLocal Consecutive Index Keys Ace Mario Halo 2016 2017 Mario Halo 2018 2019 .find({ gamertag:"Ace", game: "Halo” }) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[MinKey, MaxKey]" ], "game" : [ "["Halo", "Halo"]" ] } {} {} {} {} db.games.createIndex({gamertag:1, date:1, game:1})
  • 171. #MDBLocal Consecutive Index Keys Ace Mario Halo 2016 2017 Mario Halo 2018 2019 .find({ gamertag:"Ace", game: "Halo” }) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[MinKey, MaxKey]" ], "game" : [ "["Halo", "Halo"]" ] } {} {} {} {} db.games.createIndex({gamertag:1, date:1, game:1})
  • 172. #MDBLocal Consecutive Index Keys Ace Mario Halo 2016 2017 Mario Halo 2018 2019 .find({ gamertag:"Ace", game: "Halo” }) {} {} "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[MinKey, MaxKey]" ], "game" : [ "["Halo", "Halo"]" ] } {} {} db.games.createIndex({gamertag:1, date:1, game:1})
  • 173. #MDBLocal Consecutive Index Keys Ace Mario Halo 2016 2017 Mario Halo 2018 2019 .find({ gamertag:"Ace", game: "Halo” }) {} {} "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[MinKey, MaxKey]" ], "game" : [ "["Halo", "Halo"]" ] } {} {} db.games.createIndex({gamertag:1, date:1, game:1})
  • 174. #MDBLocal Consecutive Index Keys Ace Mario Halo 2016 2017 Mario Halo 2018 2019 .find({ gamertag:"Ace", game: "Halo” }) {} {} "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[MinKey, MaxKey]" ], "game" : [ "["Halo", "Halo"]" ] } {} {} db.games.createIndex({gamertag:1, date:1, game:1})
  • 175. #MDBLocal Consecutive Index Keys Ace Mario Halo 2016 2017 Mario Halo 2018 2019 .find({ gamertag:"Ace", game: "Halo” }) {} {} "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[MinKey, MaxKey]" ], "game" : [ "["Halo", "Halo"]" ] } {} {} db.games.createIndex({gamertag:1, date:1, game:1})
  • 176. #MDBLocal Consecutive Index Keys Ace Mario Halo 2016 2017 Mario Halo 2018 2019 .find({ gamertag:"Ace", game: "Halo” }) {} {} "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[MinKey, MaxKey]" ], "game" : [ "["Halo", "Halo"]" ] } {} {} db.games.createIndex({gamertag:1, date:1, game:1})
  • 177. #MDBLocal Consecutive Index Keys .find({ gamertag:"Ace", game: "Halo” }) {} {} {} {} "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[MinKey, MaxKey]" ], "game" : [ "["Halo", "Halo"]" ] } Halo Ace Mario Halo 2016 2017 Mario 2018 2019 "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "game" : [ "["Halo", "Halo"]" ] } db.games.createIndex({gamertag:1, game:1})
  • 178. #MDBLocal Ace 2016 2017Mario2018 2019Halo Consecutive Index Keys .find({ gamertag:"Ace", game: "Halo” }) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "game" : [ "["Halo", "Halo"]" ] } "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "game" : [ "["Halo", "Halo"]" ], "date" : [ "[MinKey, MaxKey]" ] } "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "game" : [ "["Halo", "Halo"]" ] } {}{} {}{} db.games.createIndex({gamertag:1, game:1, date:1})
  • 179. #MDBLocal R E E E E E E Consecutive Index Keys R Look familiar? This is equality after range!
  • 180. #MDBLocal Roadmap E-S-R Overview Guidelines: • Eà R • Eà S • Sà R E-S-R Considerations Operator Type Checks Consecutive Index Keys Exceptions?
  • 181. #MDBLocal Exceptions Is the E-S-R “rule” always optimal? Nope. Consider the following query: db.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1})
  • 182. #MDBLocal Exceptionsdb.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace 1 5,000 9,0012 9,000 … … 2001 2000 2015 2019 2019 gamertag score date {} {} {} {1} {2} db.games.createIndex({gamertag:1, score:1, date:1})
  • 183. #MDBLocal Exceptionsdb.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace 1 5,000 9,0012 9,000 … … 2001 2000 2015 2019 2019 gamertag score date {} {} {} db.games.createIndex({gamertag:1, score:1, date:1}) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "score" : [ "[MinKey, MaxKey]" ], "date" : [ "[2019.0, inf.0]" ] } {1} {2}
  • 184. #MDBLocal Exceptionsdb.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace 1 5,000 9,0012 9,000 … … 2001 2000 2015 2019 2019 gamertag score date {} {} {} db.games.createIndex({gamertag:1, score:1, date:1}) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "score" : [ "[MinKey, MaxKey]" ], "date" : [ "[2019.0, inf.0]" ] } {1} {2}
  • 185. #MDBLocal Exceptionsdb.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace 1 5,000 9,0012 9,000 … … 2001 2000 2015 2019 2019 gamertag score date {} {} {} db.games.createIndex({gamertag:1, score:1, date:1}) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "score" : [ "[MinKey, MaxKey]" ], "date" : [ "[2019.0, inf.0]" ] } {1} {2}
  • 186. #MDBLocal Exceptionsdb.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace 1 5,000 9,0012 9,000 … … 2001 2000 2015 2019 2019 gamertag score date {} {} {} db.games.createIndex({gamertag:1, score:1, date:1}) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "score" : [ "[MinKey, MaxKey]" ], "date" : [ "[2019.0, inf.0]" ] } {1} {2}
  • 187. #MDBLocal Exceptionsdb.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace 1 5,000 9,0012 9,000 … … 2001 2000 2015 2019 2019 gamertag score date {} {} {} db.games.createIndex({gamertag:1, score:1, date:1}) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "score" : [ "[MinKey, MaxKey]" ], "date" : [ "[2019.0, inf.0]" ] } {1} {2}
  • 188. #MDBLocal Exceptionsdb.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace 1 5,000 9,0012 9,000 … … 2001 2000 2015 2019 2019 gamertag score date {} {} {} db.games.createIndex({gamertag:1, score:1, date:1}) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "score" : [ "[MinKey, MaxKey]" ], "date" : [ "[2019.0, inf.0]" ] } {1} {2}
  • 189. #MDBLocal Exceptionsdb.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace 1 5,000 9,0012 9,000 … … 2001 2000 2015 2019 2019 gamertag score date {} {} {} db.games.createIndex({gamertag:1, score:1, date:1}) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "score" : [ "[MinKey, MaxKey]" ], "date" : [ "[2019.0, inf.0]" ] } {1} {2}
  • 190. #MDBLocal Exceptionsdb.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace 1 5,000 9,0012 9,000 … … 2001 2000 2015 2019 2019 gamertag score date {} {} {} db.games.createIndex({gamertag:1, score:1, date:1}) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "score" : [ "[MinKey, MaxKey]" ], "date" : [ "[2019.0, inf.0]" ] } {1} {2}
  • 191. #MDBLocal Exceptionsdb.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace 1 5,000 9,0012 9,000 … … 2001 2000 2015 2019 2019 gamertag score date {} {} {} db.games.createIndex({gamertag:1, score:1, date:1}) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "score" : [ "[MinKey, MaxKey]" ], "date" : [ "[2019.0, inf.0]" ] } {1} {2}
  • 192. #MDBLocal Exceptionsdb.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace 1 5,000 9,0012 9,000 … … 2001 2000 2015 2019 2019 gamertag score date {} {} {} db.games.createIndex({gamertag:1, score:1, date:1}) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "score" : [ "[MinKey, MaxKey]" ], "date" : [ "[2019.0, inf.0]" ] } {1} {2}
  • 193. #MDBLocal Exceptionsdb.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace 1 5,000 9,0012 9,000 … … 2001 2000 2015 2019 2019 gamertag score date {} {} {} db.games.createIndex({gamertag:1, score:1, date:1}) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "score" : [ "[MinKey, MaxKey]" ], "date" : [ "[2019.0, inf.0]" ] } {1} {2}
  • 194. #MDBLocal Exceptionsdb.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace 1 5,000 9,0012 9,000 … … 2001 2000 2015 2019 2019 gamertag score date {} {} {} db.games.createIndex({gamertag:1, score:1, date:1}) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "score" : [ "[MinKey, MaxKey]" ], "date" : [ "[2019.0, inf.0]" ] } {1} {2}
  • 195. #MDBLocal Exceptionsdb.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace 1 5,000 9,0012 9,000 … … 2001 2000 2015 2019 2019 gamertag score date {} {} {} db.games.createIndex({gamertag:1, score:1, date:1}) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "score" : [ "[MinKey, MaxKey]" ], "date" : [ "[2019.0, inf.0]" ] } {1} {2}
  • 196. #MDBLocal Exceptionsdb.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace 1 5,000 9,0012 9,000 … … 2001 2000 2015 2019 2019 gamertag score date {} {} {} db.games.createIndex({gamertag:1, score:1, date:1}) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "score" : [ "[MinKey, MaxKey]" ], "date" : [ "[2019.0, inf.0]" ] } {1} {2}
  • 197. #MDBLocal Exceptionsdb.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace 1 5,000 9,0012 9,000 … … 2001 2000 2015 2019 2019 gamertag score date {} {} {} "executionStats" : { "nReturned" : 2, "executionTimeMillis" : 23, "totalKeysExamined" : 9001, "totalDocsExamined" : 2, db.games.createIndex({gamertag:1, score:1, date:1}) {1} {2}
  • 199. #MDBLocal Exceptionsdb.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace 2001 2000 2015 2019 2019 {score:2} {score:1} {score:5000} {score:9001} {score:9000} … … gamertag date
  • 200. #MDBLocal Exceptionsdb.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace … … 2000 2001 2015 2019 2019 {score:2} {score:1} {score:5000} {score:9001} {score:9000} gamertag date db.games.createIndex({gamertag:1, date:1}) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[2019.0, inf.0]" ] }
  • 201. #MDBLocal Exceptionsdb.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace … … 2000 2001 2015 2019 2019 {score:2} {score:1} {score:5000} {score:9001} {score:9000} gamertag date db.games.createIndex({gamertag:1, date:1}) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[2019.0, inf.0]" ] }
  • 202. #MDBLocal Exceptionsdb.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace … … 2000 2001 2015 2019 2019 {score:2} {score:1} {score:5000} {score:9001} {score:9000} gamertag date db.games.createIndex({gamertag:1, date:1}) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[2019.0, inf.0]" ] }
  • 203. #MDBLocal Exceptionsdb.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace … … 2000 2001 2015 2019 2019 {score:2} {score:1} {score:5000} {score:9001} {score:9000} gamertag date db.games.createIndex({gamertag:1, date:1}) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[2019.0, inf.0]" ] }
  • 204. #MDBLocal Exceptionsdb.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace … … 2000 2001 2015 2019 2019 {score:2} {score:1} {score:5000} {score:9001} {score:9000} gamertag date db.games.createIndex({gamertag:1, date:1}) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[2019.0, inf.0]" ] }
  • 205. #MDBLocal Exceptionsdb.games .find({gamertag:"Ace", date:{$gte:2019}}) .sort({score:1}) Ace … … 2000 2001 2015 2019 2019 {score:2} {score:1} {score:5000} gamertag date {score:9001} {score:9000} BS "executionStats" : { "nReturned" : 2, "executionTimeMillis" : 0, "totalKeysExamined" : 2, "totalDocsExamined" : 2, "executionStats" : { "nReturned" : 2, "executionTimeMillis" : 0, "totalKeysExamined" : 2, "totalDocsExamined" : 2, "executionStages" : { "stage" : "SORT", "memUsage" : 154, "memLimit" : 33554432, db.games.createIndex({gamertag:1, date:1}) "indexBounds" : { "gamertag" : [ "["Ace", "Ace"]" ], "date" : [ "[2019.0, inf.0]" ] }
  • 208. #MDBLocal E-S-R Guidance A good starting place applicable to most use cases Place keys in the following order: Equality first Sort next Range last Remember: • Some operators may be range instead of equality • Having consecutive keys used in the index is important • Specifics about your data set may need a different approach