MongoDB 索引概念

术语

  • Covered Query/FETCH——查询覆盖/抓取

    如果所有需要的字段都在索引中,不需要额外的字段,就可以不再需要从数据页加载数据,这就是查询覆盖。

    db.human.createlndex(ffirstName:1,lastName:1
    gender:1,age:1})
    
    
  • IXSCAN/COLLSCAN——索引扫描/集合扫描

    • ixscan = index scan 索引扫描
    • coolscan 集合扫描
  • Big O Notation-时间复杂度

  • Query Shape——查询的形状

    查询用到了哪些字段

    不同的字段,对索引是有影响的

  • Index Prefix——索引前缀

    db.human.createIndex({firstName:1,lastName:1,gender:1,age:1})
    
    
    以上索引的全部前缀包括:
    {firstName:1}
    {firstName:1,lastName:1}
    {firstName:1,lastName:1,gender:1}
    
    # 所有索引前缀都可以被该索引覆盖,没有必要针对这些查询建立额外的索引
    
  • Selectivity——过滤性

    查询条件使用的字段返回结果,越精确、结果集越小、越好。


索引树结构

索引背后是B-树。要正确使用索引,必须先了解B-树的工作原理。

image-20220105124701375

B-树:基于B树,但是子节点数量可以超过2个

数据结构与算法复习

由于B树/B-树的工作过程过于复杂,但本质上它是一个有序的数据结构。我们用数组来理解它。假设索引为{a:1}(a升序):


索引执行计划

image-20220105132955181

假设集合有两个索引
1.{city:1}
2.{last_name:1}
查询:
db.members.find({city:"LA",last_name:"parker"])

Mongodb中所谓的执行计划,更多的是选择哪个索引

评估执行计划的方式:用几个线程同时跑几个索引,看哪个索引能够最快返回想要的结果。

得出结果后,会把这个执行计划保存(缓存)起来,下次继续使用


explain()

--写入10000条文档
for(var i=1;i<100000;i++)
	db.col.insert({name:i,age:i,date:new Date()})

--查询
db.col.find({name:1111}).explain(true)


执行计划中需要关注的内容:
"nReturned":1,				# 返回的数据行
"execution TimeMillis":58,	# 执行多少时间
"totalKeysExamined":0,		# 扫描多少个索引项
"totalDocsExamined":99999,	# 扫描多少个文档
"stage":"COLLSCAN",			# 查看存储扫描的类型,是ixscan,collscan还是其他类型
"docsExamined":99999

# 扫描99999个文档,返回1条数据,耗时58秒,这个执行计划是非常糟糕的


"nReturned":1,				# 返回的数据行
"execution TimeMillis":3,	# 执行多少时间
"totalKeysExamined":1,		# 扫描1个索引项
"totalDocsExamined":1,		# 扫描1个文档
"stage":"IXSCAN",			# 查看存储扫描的类型,是ixscan,collscan还是其他类型

# 扫描1个索引项,扫描1个文档,返回1个结果,耗时3秒。这是最理想状态,完全命中索引


posted @ 2022-05-19 23:38  oldSimon  阅读(241)  评论(0编辑  收藏  举报