mongodb索引笔记

  1. 索引可以加快查询速度,但是会让insert,update,delete等写操作变慢

  2. 索引在某些情况下可能导致查询变慢:

    • 查询所有:db.collections.find({}), 无索引更快, 因为有索引的话,就分2步,先找索引,再找记录
    • 太小的collecions
    • 太小的documents
  3. 索引可以使sort()变快

    • 如果排序有多个字段,index只有一个字段, 应该是没啥效果的
      • db.users.find().sort({“age” : 1, “username” : 1})
      • createIndex({“username” : 1})或createIndex({“age” : 1})都是没啥效果的
      • 最好设置index为 db.users.createIndex({“age” : 1, “username” : 1})
    • natural order: 一个不经过排序的查询结果
    • 排序与index
      • 如果排序只有一个字段,对应的也是单个的index, 那么升序,降序都可以用这个index
        • sort({“age”:1})/sort({“age”:-1}) 都可以用这个索引: createIndex({“age”:1})
      • {“age” : 1, “username” : -1}和{“age” : -1, “username” : 1}是一样的
  4. 有索引和无索引(命中索引和未命中索引)可能导致返回不一样的值

  5. 索引的类型:

    • 唯一索引(Unique Indexes), 与MySQL一样,
    • 部分索引(Partial Indexes), 因为某些字段在某些documents是可以不存在的
      db.users.ensureIndex({"email" : 1}, {"unique" : true,"partialFilterExpression" :{ email: { $exists: true } }})
      
    • 联合唯一索引(Compound unique indexes)
      复合索引保证这几个字段联合起来是唯一的
      
  6. 创建在collections上, 同样的index只能创建一个

  7. index保存在每个database的system.indexes里, 不能直接修改这个collection

  8. record identifier: 存储引擎里的东西,索引会指向他

  9. query shape: A combination of query predicate, sort, and projection

  10. query's plans: For a query, the MongoDB query optimizer chooses and caches the most efficient query plan given the available indexes

  11. covered query(覆盖索引查询)

    • https://blog.csdn.net/fly910905/article/details/78315046
    • explain的表现
      • IXSCAN stage不是FETCHstage的后代
      • executionStats.totalDocsExamined为0
  12. 隐式索引

    • 创建索引: {“a”: 1, “b”: 1, “c”: 1, …, “z”: 1}
    • 隐式索引: {“a”: 1}, {“a”: 1, “b” : 1}, {“a”: 1,“b”: 1, “c”: 1}, {“a”:1, “c”:1}
    • 非隐式索引: {“b”: 1} or {“a”: 1, “c”: 1}, {“b”:1,“c”:1}
  13. 导致索引低效的操作符

    • $ne
    • $nin
    • $not
  14. 一个查询基本上只用到一个索引

    • 对于{“x”:123, “y”:456}这样的查询
    • 只有{“x”:1}和{“y”:1}这2个索引,只会用到其中一个
    • $or操作符例外,每一个条件都是一个单独的查询,然后合并去重,可以用到多个index
  15. $in$or

    • 优先使用$in而不是$or,基于上面所说的$or是多个查询合并的
    • $in返回的是无序的: {“x” : {“KaTeX parse error: Expected 'EOF', got '}' at position 15: in" : [1, 2,3]}̲}和 {"x" : {"in” : [3, 2,1]}}返回顺序可能是一样的
  16. 复合index

    包含多个字段的index

    db.users.createIndex({“age”:1, “username” : 1})

    • db.users.find({“age” : 21}).sort({“username” : -1}), ok
    • db.users.find({“age” : {“ g t e " : 21 , " gte" : 21, " gte":21,"lte” : 30}}), ok
    • db.users.find({“age” : {“ g t e " : 21 , " gte" : 21, " gte":21,"lte” :30}}).sort({“username” : 1}), not ok
      • 改进,更改index顺序: db.users.createIndex( {“username” : 1, “age” : 1})
      • 多个字段索引, 通常把sort的field放在多字段索引的第一个字段
    • 设计准则:
      • 有相等查询(equality filters)字段放前面
      • 有排序字段放在相等查询字段之后,范围查询(比如: 大于某个值,小于某个值)字段之前(好像有问题)
      • 范围查询字段放最后
  17. multikey index
    - 如果index里有字段是array就被标记为multikey index
    - 在explain里命中这个索引后, isMultiKey为True
    - index一旦被标记为multikey index,那怕相关的doc被删除都还是这个标记, 只有删除index,然后重建才可以抹掉这个标记

  18. .explain(“executionStats”)

    用于为find()提供query plan的信息, 跟MySQL的explain指令差不多:

    用法: db.collName.find({}).explain(), 或者 db.collName.find({}).explain(“executionsStats”)

    • .explain("executionsStats")返回结果里的关键字段
      • COLLSCAN字段: 没用到索引,作了全文扫描
      • SORT字段: 如果有这个 stage在结果里,那么这就是比较糟糕的: 排序没有用到索引,在内存里排序了,如果超过32M还会报错
      • executionTimeMillis字段: 实际执行时间
      • nReturned字段: 实际返回的条数
      • totalKeysExamined字段: 检查的index的条数,与nReturned一致是最好的
      • totalDocsExamined字段: 检查的documentation的条数,与nReturned一致是最好的
  19. .createIndex()

    创建索引,createIndex({“filedName”:1, “fieldName”:-1})

    • 顺序: 字段名后面为1是升序, -1是降序
  20. .hint()

    强制使用某个索引,参数可以是索引名字, 也可以是shape

    • 指定索引: db.users.find().hint( { age: 1 } )
    • 索引名: db.users.find().hint( “age_1” )
  21. 查询计划: https://zhuanlan.zhihu.com/p/47281465

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值