今天要分享的是, 关于 MongoDB 的覆盖索引查询和查询分析, 东西不多, 大家可以将就着看看. 接下来直接进入正题哈. 官方的 MongoDB 的文档中说明, 覆盖查询是以下的查询:
所有的查询字段是索引的一部分
所有的查询返回字段在同一个索引中
由于所有出现在查询中的字段是索引的一部分, MongoDB 无需在整个数据文档中检索匹配查询条件和返回使用相同索引的查询结果. 因为索引存在于 RAM 中, 从索引中获取数据比通过扫描文档读取数据要快得多. 接下来, 为了测试覆盖索引查询, 使用以下 users 集合:
- {"_id": ObjectId("53402597d852426020000002"),
- "contact": "987654321",
- "dob": "01-01-1991",
- "gender": "M",
- "name": "Tom Benzamin",
- "user_name": "tombenzamin"
- }
我们在 users 集合中创建联合索引, 字段为 gender 和 user_name:
>db.users.ensureIndex({gender:1,user_name:1})
现在, 该索引会覆盖以下查询:
>db.users.find({gender:"M"},{user_name:1,_id:0})
也就是说, 对于上述查询, MongoDB 的不会去数据库文件中查找. 相反, 它会从索引中提取数据, 这是非常快速的数据查询. 由于我们的索引中不包括 _id 字段,_id 在查询中会默认返回, 我们可以在 MongoDB 的查询结果集中排除它. 下面的实例没有排除_id, 查询就不会被覆盖:
>db.users.find({gender:"M"},{user_name:1})
最后说明一下, 如果所有索引字段是一个数组的查询, 不能使用覆盖索引查询, 也就是说所有索引字段是一个子文档.
接下来看一下查询分析哈. MongoDB 查询分析可以确保我们建议的索引是否有效, 是查询语句性能分析的重要工具. MongoDB 查询分析常用函数有: explain() 和 hint(). 然后呢, 我们先来看一下 explain()这个函数, explain 操作提供了查询信息, 使用索引及查询统计等. 有利于我们对索引的优化. 接下来我们在 users 集合中创建 gender 和 user_name 的索引:
>db.users.ensureIndex({gender:1,user_name:1})
现在在查询语句中使用 explain:
- >db.users.find({gender:"M"},{user_name:1,_id:0}).explain()
- {
- "cursor" : "BtreeCursor gender_1_user_name_1",
- "isMultiKey" : false,
- "n" : 1,
- "nscannedObjects" : 0,
- "nscanned" : 1,
- "nscannedObjectsAllPlans" : 0,
- "nscannedAllPlans" : 1,
- "scanAndOrder" : false,
- "indexOnly" : true,
- "nYields" : 0,
- "nChunkSkips" : 0,
- "millis" : 0,
- "indexBounds" : {
- "gender" : [
- [
- "M",
- "M"
- ]
- ],
- "user_name" : [
- [
- {
- "$minElement" : 1
- },
- {
- "$maxElement" : 1
- }
- ]
- ]
- }
- }
现在, 我们看看这个结果集的字段:
indexOnly: 字段为 true , 表示我们使用了索引.
cursor: 因为这个查询使用了索引, MongoDB 中索引存储在 B 树结构中, 所以这是也使用了 BtreeCursor 类型的游标. 如果没有使用索引, 游标的类型是 BasicCursor. 这个键还会给出你所使用的索引的名称, 你通过这个名称可以查看当前数据库下的 system.indexes 集合 (系统自动创建, 由于存储索引信息, 这个稍微会提到) 来得到索引的详细信息.
n: 当前查询返回的文档数量.
nscanned/nscannedObjects: 表明当前这次查询一共扫描了集合中多少个文档, 我们的目的是, 让这个数值和返回文档的数量越接近越好.
millis: 当前查询所需时间, 毫秒数.
indexBounds: 当前查询具体使用的索引.
然后呢, 咱们再来看一下所谓的 hint()函数. 虽然 MongoDB 查询优化器一般工作的很不错, 但是也可以使用 hint 来强制 MongoDB 使用一个指定的索引. 这种方法某些情形下会提升性能. 一个有索引的 collection 并且执行一个多字段的查询(一些字段已经索引了). 如下查询实例指定了使用 gender 和 user_name 索引字段来查询:
>db.users.find({gender:"M"},{user_name:1,_id:0}).hint({gender:1,user_name:1})
我们可以使用 explain() 函数来分析以上查询:
>db.users.find({gender:"M"},{user_name:1,_id:0}).hint({gender:1,user_name:1}).explain()
OK, 本次的分享到这里就差不多结束了. 声明一下哈, 本人学习笔记, 各位看官勿喷哈, 如果感觉不错, 请多多点赞支持哦.
来源: https://blog.csdn.net/luyaran/article/details/79847903