Indexing and Query Optimization
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Indexing and Query Optimization

on

  • 1,131 views

 

Statistics

Views

Total Views
1,131
Views on SlideShare
991
Embed Views
140

Actions

Likes
0
Downloads
14
Comments
0

3 Embeds 140

http://www.10gen.com 110
http://www.mongodb.com 29
http://drupal1.10gen.cc 1

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • First part of this talk is more conceptualSecond part is more detailed and MongoDB specific.
  • Not just a database concept, have been around for a long timeServe the same purpose: access information quickly and efficiently.
  • Find recipe by name: CurrywurstHere: compound index on (Reipe Type, Name, Page Number)
  • Really depends on the order
  • Humans have ability to quickly skim over the recipe page and find the name they are looking forMove into the world of computers:Linked lists
  • Look at 7 documents
  • Binary TreesQueries, inserts and deletes: O(log(n)) time
  • MongoDB's indexes are B-Trees.German invention: Prof. Rudolph BayerLookups (queries), inserts and deletes happen in O(log(n)) time.
  • So this is helpful, and can speed up queries by a tremendous amount
  • So it’s imperative we understand them
  • As Support Engineer, get questions about performance all the timeUsually :“Everything got really slow”“We didn’t change anything” – RIGHTLast week: They didn’t change anythingDBA ran a few queries without an indexNot only slow, slow down + blocks reads, pulled 20M documents into RAM, ejecting working set
  • As Support Engineer, get questions about performance all the timeUsually :“Everything got really slow”“We didn’t change anything” – RIGHTLast week: They didn’t change anythingDBA ran a few queries without an indexNot only slow, slow down + blocks reads, pulled 20M documents into RAM, ejecting working set
  • Repeated calls to ensureIndex only result in one create message going to the server. The index is cached client side for some period of time (varies by driver).Check Manual.
  • reIndex drops *all* indexes (including the _id index) and rebuilds themExpensive operation. Don’t need to do this often. Corruption / Fragmentation.
  • Caveats:Still a resource-intensive operationIndex build is slowerIndexes are still built in the foreground on secondaries
  • Repeat what wejust did:Basic operationsNow looking at some of the options and different index types
  • unique applies a uniqueness constant on duplicate values.dropDups will force the server to create a unique index by only keeping the first document found in natural order with a value and dropping all other documents with that value.dropDups will likely result in data loss!!!
  • MongoDB doesn't enforce a schemaSparse indexes only contain entries for documents that have the indexed field.With sparse a unique constraint can be applied to a field not shared by all documents. Otherwise multiple 'null' values violate the unique constraint.Useful? Imagine: high_priority tag on only 1 % of your data. Can use sparse index to retrieve quickly.
  • Only touch on Geo indexes.'2d' index is a geohash on top of the b-tree.Allows you to search for documents 'near' a long/lat position. Bounds queries are also possible using $within.Good for mobile apps: Find 50 nearest “currywurstbuden” close to me2.4 brings even more geo features.
  • Index must be on a BSON date field.Documents are removed after expireAfterSeconds seconds.Reaper thread runs every 60 seconds.
  • Indexes are a really powerful feature of MongoDB, so you need to understand the limitations.*With the exception of $or queries.If index key exceeds 1k, documents silently dropped/not included
  • Another question we often get in Support:How do we know that our indexes are efficientHow do we know that our queries use the right indexes
  • n=2 lot of writes to profile collection, usually n=1.
  • cursor – the type of cursor used. BasicCursor means no index was used. TODO: Use a real example here instead of made up numbers…n – the number of documents that match the querynscannedObjects – the number of documents that had to be scannednscanned – the number of items (index entries or documents) examinedmillis – how long the query tookRatio of n to nscanned should be as close to 1 as possible.
  • cursor – the type of cursor used. BasicCursor means no index was used.n – the number of documents that match the querynscannedObjects – the number of documents that had to be scannednscanned – the number of items (index entries or documents) examinedmillis – how long the query tookRatio of n to nscanned should be as close to 1 as possible.
  • Winning plan is reevaluated after 1000 write operations (insert, update, remove, etc.).
  • Tells MongoDB exactly what index to use.
  • MongoDB sorts results based on the field order in the index.For queries that include a sort that uses a compound key index, ensure that all fields before the first sorted field are equality matches.Add slide before this to explain sorting. Also: break
  • MongoDB sorts results based on the field order in the index.For queries that include a sort that uses a compound key index, ensure that all fields before the first sorted field are equality matches.
  • Rework to go along with the cookbook example
  • SupportThese things come up oftenUnderstand now, don’t make same mistakes
  • Better to use a compound index on the low selectivity field and some other more selective field.

Indexing and Query Optimization Presentation Transcript

  • 1. #MongoDBDaysIndexing and QueryOptimizationThomas RückstießTechnical Support Engineerthomas@10gen.com
  • 2. Agenda• What are indexes?• Why do I need them?• Working with indexes in MongoDB• Optimize your queries• Avoiding common mistakes
  • 3. What are indexes?
  • 4. KRISTINE TO INSERT IMAGE OF COOKBOOKFind a recipe by name:“Currywurst”
  • 5. What are indexes? • How would you find a recipe using chicken? • How about a 300-500 calorie recipe using chicken?Chicken 88 kcal 88 kcal: Chicken soup Chicken: Chicken soup 356 kcal: Chicken Ceasar Salad 356 kcal 480 kcal: Teriyaki Chicken Chicken: Chicken Ceasar Salad 680 kcal: Buffalo Chicken Wings 412 kcalFish Fish: Tuna Sandwich 412 kcal: Tuna Sandwich 480 kcalPork Pork: Curry Wurst 480 kcal: Curry Wurst Chicken: Teriyaki Chicken 680 kcal Chicken: Buffalo Chicken Wings
  • 6. 1 2 3 4 5 6 7 Linked List
  • 7. 1 2 3 4 5 6 7 Finding 7 in Linked List
  • 8. 4 2 61 3 5 7 Finding 7 in Tree
  • 9. Indexes in MongoDB are B-trees
  • 10. Indexes are the singlebiggest tunableperformance factor inMongoDB
  • 11. Absent or suboptimalindexes are the mostcommon avoidableMongoDB performanceproblem.
  • 12. Why do I need indexes?A brief story 5 min 30 sec
  • 13. Why do I need indexes? 3h
  • 14. Working with Indexes inMongoDB
  • 15. How do I create indexes?// The client remembers the index and raises no errorsdb.recipes.ensureIndex({ main_ingredient: 1 })* 1 means ascending, -1 descending
  • 16. What can be indexed?// Multiple fields (compound indexes)db.recipes.ensureIndex({ main_ingredient: 1, calories: -1})// Arrays of values (multikey indexes){ name: ’Curry Wurst mit Pommes’, ingredients : [’pork, ’curry]}db.recipes.ensureIndex({ ingredients: 1 }) Image: http://www.marions-kochbuch.com/
  • 17. What can be indexed?// Subdocuments{ name : ’Curry Wurst mit Pommes, contributor: { name: ’Hans Wurst, id: ’hawu36 }}db.recipes.ensureIndex({ contributor.id: 1 })db.recipes.ensureIndex({ contributor: 1 }) Image: http://www.marions-kochbuch.com/
  • 18. How do I manage indexes?// List a collections indexesdb.recipes.getIndexes()db.recipes.getIndexKeys()// Drop a specific indexdb.recipes.dropIndex({ ingredients: 1 })// Drop all indexes and recreate themdb.recipes.reIndex()// Default (unique) index on _id
  • 19. Background Index Builds// Index creation is a blocking operation that can take a long time// Background creation yields to other operationsdb.recipes.ensureIndex( { ingredients: 1 }, { background: true })
  • 20. Options• Uniqueness constraints (unique, dropDups)• Sparse Indexes• Geospatial (2d) Indexes• TTL Collections (expireAfterSeconds)
  • 21. Uniqueness Constraints// Only one recipe can have a given value for namedb.recipes.ensureIndex( { name: 1 }, { unique: true } )// Force index on collection with duplicate recipe names – drop theduplicatesdb.recipes.ensureIndex( { name: 1 }, { unique: true, dropDups: true })* dropDups is probably never what you want image: www.idownloadblog.com
  • 22. Sparse Indexes// Only documents with field calories will be indexeddb.recipes.ensureIndex( { calories: -1 }, { sparse: true })// Allow multiple documents to not have calories fielddb.recipes.ensureIndex( { name: 1 , calories: -1 }, { unique: true, sparse: true })* Missing fields are stored as null(s) in the index
  • 23. Geospatial Indexes// Add latitude, longitude coordinates{ name: ’Curry 36 am Mehringdamm’, loc: [ 13.387764, 52.493442]}// Index the coordinatesdb.locations.ensureIndex( { loc : 2d } )// Query for locations near a particular coordinatedb.locations.find({ loc: { $near: [ 37.4, -122.3 ] }}) image: NASA
  • 24. TTL Collections// Documents must have a BSON UTC Date field{ ’submitted_date : ISODate(2012-10-12T05:24:07.211Z), … }// Documents are removed after// expireAfterSeconds secondsdb.recipes.ensureIndex( { submitted_date: 1 }, { expireAfterSeconds: 3600 }) image: taylordsdn112.wordpress.com
  • 25. Limitations• Collections can not have > 64 indexes.• Index keys can not be > 1024 bytes (1K).• The name of an index, including the namespace, must be < 128 characters.• Queries can only use 1 index*• Indexes have storage requirements, and impact the performance of writes.• In memory sort (no-index) limited to 32mb of return data.
  • 26. Optimize Your Queries
  • 27. Profiling Slow Opsdb.setProfilingLevel( n , slowms=100ms )n=0 profiler offn=1 record operations longer than slowmsn=2 record all queriesdb.system.profile.find()* The profile collection is a capped collection, and fixed in size image: http://www.speareducation.com/
  • 28. The Explain Plan (withoutIndex)db.recipes.find( { calories: { $lt : 40 } }).explain( ){ "cursor" : "BasicCursor" , "n" : 42, "nscannedObjects” : 12345 "nscanned" : 12345, ... "millis" : 356, ...}* Doesn’t use cached plans, re-evals and resets cache
  • 29. The Explain Plan (with Index)db.recipes.find( { calories: { $lt : 40 } }).explain( ){ "cursor" : "BtreeCursor calories_-1" , "n" : 42, "nscannedObjects": 42 "nscanned" : 42, ... "millis" : 0, ...}* Doesn’t use cached plans, re-evals and resets cache
  • 30. The Query Optimizer• For each "type" of query, MongoDB periodically tries all useful indexes• Aborts the rest as soon as one plan wins• The winning plan is temporarily cached for each “type” of query
  • 31. Manually Select Index to Use// Tell the database what index to usedb.recipes.find({ calories: { $lt: 1000 } }).hint({ _id: 1 })// Tell the database to NOT use an indexdb.recipes.find( { calories: { $lt: 1000 } }).hint({ $natural: 1 })
  • 32. Use Indexes to Sort QueryResults// Given the following indexdb.collection.ensureIndex({ a:1, b:1 , c:1, d:1 })// The following query and sort operations can use the indexdb.collection.find( ).sort({ a:1 })db.collection.find( ).sort({ a:1, b:1 })db.collection.find({ a:4 }).sort({ a:1, b:1 })db.collection.find({ b:5 }).sort({ a:1, b:1 })
  • 33. Indexes that won’t work forsorting query results// Given the following indexdb.collection.ensureIndex({ a:1, b:1, c:1, d:1 })// These can not sort using the indexdb.collection.find( ).sort({ b: 1 })db.collection.find({ b: 5 }).sort({ b: 1 })
  • 34. Index Covered Queries// MongoDB can return data from just the indexdb.recipes.ensureIndex({ main_ingredient: 1, name: 1 })// Return only the ingredients fielddb.recipes.find( { main_ingredient: chicken’ }, { _id: 0, name: 1 })// indexOnly will be true in the explain plandb.recipes.find( { main_ingredient: chicken }, { _id: 0, name: 1 }).explain(){ "indexOnly": true,}
  • 35. Absent or suboptimalindexes are the mostcommon avoidableMongoDB performanceproblem.
  • 36. Avoiding CommonMistakes
  • 37. Trying to Use MultipleIndexes// MongoDB can only use one index for a querydb.collection.ensureIndex({ a: 1 })db.collection.ensureIndex({ b: 1 })// Only one of the above indexes is useddb.collection.find({ a: 3, b: 4 })
  • 38. Compound Key Mistakes// Compound key indexes are very effectivedb.collection.ensureIndex({ a: 1, b: 1, c: 1 })// But only if the query is a prefix of the index// This query cant effectively use the indexdb.collection.find({ c: 2 })// …but this query candb.collection.find({ a: 3, b: 5 })
  • 39. Low Selectivity Indexesdb.collection.distinct(status’)[ new, processed ]db.collection.ensureIndex({ status: 1 })// Low selectivity indexes provide little benefitdb.collection.find({ status: new })// Betterdb.collection.ensureIndex({ status: 1, created_at: -1 })db.collection.find( { status: new }).sort({ created_at: -1 })
  • 40. Regular Expressionsdb.users.ensureIndex({ username: 1 })// Left anchored regex queries can use the indexdb.users.find({ username: /^hans wurst/ })// But not generic regexesdb.users.find({username: /wurst/ })// Or case insensitive queriesdb.users.find({ username: /Hans/i })
  • 41. Negation// Indexes arent helpful with negationsdb.things.ensureIndex({ x: 1 })// e.g. "not equal" queriesdb.things.find({ x: { $ne: 3 } })// …or "not in" queriesdb.things.find({ x: { $nin: [2, 3, 4 ] } })// …or the $not operatordb.people.find({ name: { $not: ’Hans Wurst } })
  • 42. Choosing the rightindexes is one of themost important thingsyou can do as aMongoDB developer sotake the time to get yourindexes right!
  • 43. #MongoDBDaysThank youThomas RückstießTechnical Support Engineerthomas@10gen.com