MongoDB uses COLLSCAN when returning just _id

时光毁灭记忆、已成空白 提交于 2021-02-18 07:51:50

问题


I want to return all IDs from a MongoDB collection and I used the code below:

db.coll.find({}, { _id: 1})

But MongoDB scans the whole collection instead of reading the information from the default index { _id: 1 }.

From the log:

{ find: "collection", filter: {}, projection: { _id: 1 } } 
planSummary: COLLSCAN cursorid:30463374118 keysExamined:0
docsExamined:544783 numYields:4286 nreturned:544782 reslen:16777238
locks:{ Global: { acquireCount: { r: 8574 } }, Database: {
acquireCount: { r: 4287 } }, Collection: { acquireCount: { r: 4287 } }
} protocol:op_query 7024ms

Any idea how to fix this, please?


回答1:


You would need to add a filter that can use this index like so in order to change that query plan - not all operations remove the FETCH stage, e.g. $exists does not appear to work:

db.coll.find({ _id: { $ne: 0 }, { _id: 1 }) // works for ObjectIds

One part of the explanation for this is in the documentation:

A covered query is a query that can be satisfied entirely using an index and does not have to examine any documents. An index covers a query when both of the following apply:

  • all the fields in the query are part of an index,
  • and all the fields returned in the results are in the same index.

I seem to remember seeing a JIRA request to support that without the filter but cannot remember which ticket that was...




回答2:


I have found a solution, which works if one knows the type of the _id field. In case of string _id:

db.coll.find({ _id: { $regex: ".*" }, { _id: 1 })

In case of integer _id:

db.coll.find({ _id: { $gte: 0 }, { _id: 1 })


来源:https://stackoverflow.com/questions/49534020/mongodb-uses-collscan-when-returning-just-id

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!