zoukankan      html  css  js  c++  java
  • mongodb学习(六)索引

    准备工作: 先插入100万条数据

    for(i=0;i<=1000000;i++){
        db.users.insert({
               "i":i,
               "username":"user"+i,
               "age":Math.floor(Math.random()*120),
               "created":new Date()
        })
    
    }        

     1. 创建索引: 数据量越大创建索引时间越长

    db.users.ensureIndex({"username":1})
    db.users.find({"username":"user234455"}).explain()
     查询速度飞快...O(∩_∩)O~
    使用索引的代价:  添加一个索引,每次插入,更新,删除操作都会耗费更多时间;原因是数据变动时mongodb每次都要更新文档和索引. 在一个集合上通常不应该拥有两个以上的索引.
    在常用的键上建立索引.
    2. 复合索引:就是建立在多个键上的索引
        (索引在排序时非常快,前提是首先使用索引键排序)
    db.users.ensureIndex({"username":1,"age":1})//每个索引都包含 age 和 name字段

       三种使用方式:  (mongodb可以在任意方向上对索引进行遍历)

    (1) 点查询,这种最高效

    db.users.find({"age":21}).sort({"username":-1})

    (2) 多点查询: 使用索引查询出来的结果是无序的,mongodb需要在内存中重新排序,然后返回.问题:结果集文档数量比较大,查询速度会慢;结果集超过32M,mongodb会出错

    db.users.find({"age":{"$gte":20,"$lte":30}}).sort({"username":1})

    (3) 使用另一个索引 {"username":1,"age":1} 可以使用hint强制使用某个索引

    db.users.find({"age":{"$gte":20,"$lte":30}}).sort({"name":1}).explain()
    db.users.find({"age":{"$gte":20,"$lte":30}}).sort({"name":1}).hint({"name":1,"age":1}).explain()

    索引本质上是: 树,最小的值在最左边,最大的值在最右边.

    (4) 只有在基于多键排序的时候,方向才变得重要.

    (5) 覆盖索引: 索引中已经包含了要查找的字段;

    (6) 复合索引: 对不同的查询表现为不同的索引:, {"age":1,"username":1},可以"免费" 获取以age这个键开头的所有索引;

    (7) $where和检查一个键是否存在 无法使用索引; 在索引中不存在的字段和null字段的存储方式是一样的.

    (8)查询: 将精确匹配的字段放在前面,将范围匹配的字段放在最后;

    (9)$or: 可以对每个子句都使用索引,因为实际上$or执行两次查询然后将结果集合并,效率不高,尽可能使用 $in

                $or需要每次检查查询的结果集并且将重复的文档移除.

    (10)索引嵌套文档:

    db.users.ensureIndex({"loc.city":1})

    (11)对数组简历索引: 对数组建立索引实际上就是对数组中每一个元素建立索引条目,而不是对数组本身建立索引,一个索引中的数组字段最多只有一个.
    (12) 索引基数: 就是集合中每个字段拥有不同值得数量.应该再基数比较高的字段上建立索引.

    (13)explain()  可以提供大量与查询有关的信息;如果scanAndOrder为true,那么说明没有使用索引,mongodb需要再内存中排序,这回很慢

          hint() 强行使用某个索引

    db.users.find({"age":28}).hint({"age":1})

    3. 何时不应该使用索引: 结果集在原集合中所占比重越大,索引速度就越慢. 一般来说: 查询需要返回结果集30%的就需要比较 全表扫描和索引查找的速度...
        索引查找: 索引需要进行两次查找,一次是查找索引条目,一次是根据索引条目查找相应文档; 使用{"$natural":1} 强制全表扫描

    db.users.find({"age":28}).hint({"$natural":1})

    4. 索引类型:
       (1) 唯一索引: (会把null看做值)

    db.users.ensureIndex({"usename":1},{"unique":true})

      复合唯一索引: 所有键的组合值必须是唯一的.

      去除重复的索引:

    db.users.ensureIndex({"usename":1},{"unique":true,"dropDups":true})

    (2) 稀疏索引: (如果一个肯能存在也可能不存在的字段,当它存在时,它必须是唯一的),稀疏索引可以使唯一的.

    db.users.ensureIndex({"email":1},{"sparse":true})

    5. 索引管理: 数据库所有的索引都存储在system.indexes集合中; 索引顺序很重要: {"age":1,"username":1},{"username":1,"age":1}是不同的索引

    db.users.getIndexes() //uses所有的索引都可以在这里查看

    (1)索引标识:索引名称是唯一的. 可以自定义索引

    db.users.ensureIndex({"usename":1},{"name":"myIndex"})

    (2)删除索引: mongodb创建索引时会阻塞所有对数据的读写请求.一直到创建完毕

    db.users.drop("username_1")

    6. 固定集合...

     
     
     
     
     
  • 相关阅读:
    状态压缩 + 暴力 HDOJ 4770 Lights Against Dudely
    简单几何(推公式) UVA 11646 Athletics Track
    简单几何(四边形形状) UVA 11800 Determine the Shape
    简单几何(求交点) UVA 11437 Triangle Fun
    计算几何模板
    简单几何(相对运动距离最值) UVA 11796 Dog Distance
    简单几何(求划分区域) LA 3263 That Nice Euler Circuit
    覆盖的面积 HDU
    Desert King 最小比率生成树 (好题)
    约会安排 (区间合并)毒瘤题
  • 原文地址:https://www.cnblogs.com/ry123/p/3881375.html
Copyright © 2011-2022 走看看