MongoDB学习04: 索引

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/damage_e/article/details/78945707

数据量较大时,使用索引可以大大加快查询速度。
- 查看索引
db.test_collection.getIndexes()
- 创建索引
db.test_collection.ensureIndex({x:1})

索引种类

  • _id 索引(自动创建)
  • 单键索引(比较变通的索引,不会自动创建)
  • 多键索引(与单。。区别在于字段的值是单一,还是数组)
    db.test_collection.ensureIndex({x:1})
    db.test_collection.insert({x:[1,4,5,4]}) //就成了多键索引
  • 复合索引(当查询条件不只一个时,就需要建立复合索引)
    db.collection.ensureIndex({x:1,y:1})
  • 过期索引(一段时间会过期,相应数据也会被删除)
    比较适合登录信息和日志信息。
    db.collection.ensureIndex({time:1},{expireAfterSeconds:10})
    存储在过期索引的值必须是指定的时间类型,必须是ISODate或者ISODate数组,不能使用时间戳,否则不能被自动删除 ;如果ISODate是数组,则最小时间进行删除;不能是复合索引;删除时间是不精确的(每60s跑一次,删除也要一些时间)。
  • 全文索引(对字符串与字符串数组创建全文可搜索的索引)
    适用情况:{author:”“,title:”“,article:”“}
    db.articles.ensureIndex({key:"text"})
    db.articles.ensureIndex({key1:"text",key2:"text"})
    db.articles.ensureIndex({key:"text"})
    查询:
    db.articles.find({$text:{$search:"coffee"}})
    db.articles.find({$text:{$search:"aa bb cc"}}) //或查询
    db.articles.find({$text:{$search:"aa bb -cc"}}) //不包含cc串
    db.articles.find({$text:{$search:"\"aa\" \"bb\" \"cc\""}}) //与查询语句,用引号(这里要用斜线转义)
    与百度查询相同,相似度越大的在前面的查询(使用$meta):
    {score:{$meta:"textScore"}}
    db.articles.find({$text:{$search:"aa bb"}},{score:{$meta:"textScore"}})查询数据中多了一个score字段,表示相似度
    进行排序:
    db.articles.find({$text:{$search:"aa bb"}},{score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}})
    使用限制:每次查询只能指定一个 text text查询不能出现在 nor text,hint不再起作用(强制指定使用某索引进行性能测试);不支持中文。
  • 地理位置索引
    将一些点的位置存储在MongoDB中,创建索引后,可以按照位置来查找其他点。
    子分类:

    1. 2d索引,用于存储和查找平面上的点;
      查找方式:
      a. 查找距离某个点一定距离内的点。
      ensureIndex({w:"2d"}) //创建
      经度[-180,180]纬度[-90,90]
      insert({w:[1,1]}) //插入数据
      find({w:{$near:[1,1]}}) //与[1,1]距离最近的点
      find({w:{$near:[1,1],$maxDistance:10}}) // 设置最大距离范围
      b. 查找包含在某个区域内的点。
      find({w:{$geoWithin:{$box:[[0,0],[3,3]]}}}) //在矩形中的点
      find({w:{$geoWithin:{$center:[[0,0],4]}}}) //在圆中的点
      find({w:{$geoWithin:{$polygon:[[0,0],[0,1],[2,5],[6,1]]}}}) //在多边形中的点
      geoNear查询:
      db.runCommand({geoNear:<collection>,near:[x,y],minDistance:d1,maxDistance:d2,num:n1(返回数目)})
      db.runCommand({geoNear:"location",near:[1,2],maxDistance:10,num:2})

    2. 2dsphere索引,用于存储和查找球面上的点。
      ensureIndex({w:"2dsphere"})
      {type:" ",coordinates:[<coodinates>]} //位置表示
      查询与2d类似,并且支持$minDistance 与 $maxDistance,还支持交叉点

索引属性

  • name
    一般索引 x_1 或x_-1//升序与降序 ;复合索引为x_1_y_-1;可能超125字节限制自定义索引名字:ensureIndex({x:1,y:1,z:1,m:1},{name:"normal_index
  • 唯一性,unique指定:
    ensureIndex({},{unique:true/false})
  • 稀疏性,sparse指定(在不包括索引数据中不必创建索引,节约空间,增大查询速度):
    ensureIndex({},{sparse:true})
    但在$exists(用于查找一个字段存在与不存在的数据)中出现隐患
    find({m:{$exists:true}}) //只查找m存在的字段
    不能在稀疏索引上查找不存在的记录。
  • 是否定期删除,expireAfterSeconds指定:
    TTL,过期索引

索引构建情况分析

  • 好处:加快索引相关的查询。
  • 劣势:增加磁盘空间消耗,降低写入性能。

评判当前索引构建情况

  • mongostat工具
    mongostat -h 127.0.0.1:12345
    其中 idx miss 较高,就说明创建了不合适的索引
    各指标含义:
    inserts/s 每秒插入次数
    query/s 每秒查询次数
    update/s 每秒更新次数
    delete/s 每秒删除次数
    getmore/s 每秒执行getmore次数
    command/s 每秒的命令数,比如count
    flushs/s 每秒执行fsync将数据写入硬盘的次数。
    mapped/s 所有的被mmap的数据量,单位是MB,
    vsize 虚拟内存使用量,单位MB
    res 物理内存使用量,单位MB
    faults/s 每秒访问失败数(只有Linux有),数据被交换出物理内存,放到swap。不要超过100,否则就是机器内存太小,造成频繁swap写入。此时要升级内存或者扩展
    locked % 被锁的时间百分比,尽量控制在50%以下吧
    idx miss % 索引不命中所占百分比。如果太高的话就要考虑索引是不是少了
    q t|r|w 当Mongodb接收到太多的命令而数据库被锁住无法执行完成,它会将命令加入队列。这一栏显示了总共、读、写3个队列的长度,都为0的话表示mongo毫无压力。高并发时,一般队列值会升高。
    conn 当前连接数
    time 时间戳
    Mongodb良好运行标示:
    insert query update delete 较稳定,这4列数据越大说明性能越高,如果运行一定时间后,指标骤减,说明程序处理存在问题。
    faults越小越好,越小说明操作失败率越低;
    idx miss越小越好,越小说明索引命中率越高,Mongodb索引非常重要;
    netin/netout 数据越大越好,越大说明进出数据交换越大。
  • profile集合介绍
    db.getProfilingLevel() //有0关闭,2开启,1记录超过slowms值的操作
    db.getProfilingStatus()// { "was" : 0, "slowms" : 100 }
    设置db.setProfilingLevel(2)//开启,会生成一个system.profile文档
    db.system.profile.find().sort({$natural:-1}).limit(1)
    开启后会影响到数据库的性能,只适用于系统的测试阶段和刚刚上线时观察阶段。
  • 日志介绍
    在配置文件mongod.conf下verbose=vvvvvverbose值可以是一个v到五个v.详细程度逐渐提高
  • explain分析
    find({x:1}).explain()可以查询你的查询是否用了索引和查询时间,以及扫描数量。

猜你喜欢

转载自blog.csdn.net/damage_e/article/details/78945707