Mongodb: Performance impact of $HINT

2020-05-05 01:02发布

I have a query that uses compound index with sort on "_id". The compound index has "_id" at the end of the index and it works fine until I add a $gt clause to my query.

i.e, Initial query

db.colletion.find({"field1": "blabla", "field2":"blabla"}).sort({_id:1}

Subsequent queries

db.colletion.find({"field1": "blabla", "field2":"blabla", _id:{$gt:ObjetId('...')}}).sort({_id:1}

what I am noticing is that there are times when my compound index is not used. Instead, Mongo uses the default

"BtreeCursor _id_"

To avoid this, I have added a HINT to the cursor. I'd like to know if there is going to be any performance impact? since the collection already had the index but Mongo decided to use a different index to serve my query.

One thing I noticed is that when I use the hint

"cursor" : "QueryOptimizerCursor", "n" : 1, "nscannedObjects" : 2, "nscanned" : 2, "nscannedObjectsAllPlans" : 2, "nscannedAllPlans" : 2, "scanAndOrder" : false, "nYields" : 0, "nChunkSkips" : 0, "millis" : 0, "server" : "aaa-VirtualBox:27017", "filterSet" : false

time taken is faster > millis

than when it serves the same query without hint

"cursor" : "BtreeCursor _id_", "isMultiKey" : false, "n" : 1, "nscannedObjects" : 1, "nscanned" : 1, "nscannedObjectsAllPlans" : 3, "nscannedAllPlans" : 3, "scanAndOrder" : false, "indexOnly" : false, "nYields" : 0, "nChunkSkips" : 0, "millis" : 3,

Is there a trade off of using HINT which I am overlooking? Will this performance be the same on a large collection?

1条回答
祖国的老花朵
2楼-- · 2020-05-05 01:33

Can you please specify the compound index you have created. I don't have much reputation so i couldn't ask this in comment. But i do have a possible anwer to your question. Mongo uses a property called "Equality-Sort-Range" which behaves in a different manner. Consider below situation- You have few documents with fields {name : string, pin : six digit number, SSN : nine digit number} and you have two indices as - {name: 1, pin: 1, ssn: 1} and second index is {name: 1, ssn :1, pin :1} now consider below queries:

  1. db.test.find({name: "XYZ", pin: 123456"}).sort({ssn: 1}) This query will use the first index because we have compound index in continuation. Name, pin, ssn are in continuation.
  2. db.test.find({name: "XYZ", pin: {$gt :123456"}}).sort({ssn: 1}) You will expect that first index will be used in this query. But surprisingly seconds index will be used by this query because it has a range operation on pin.

Equality-sort-range property says that query planner will use the index on field which serve - "equality-sort-range" better. Second query has range on pin so second index will be used while first query has equality on all fields so first index will be used.

查看更多
登录 后发表回答