MongoDB优化
MongoDB索引与优化
## 索引优化准则 - 根据ESR原则创建索引:精确(Equal)匹配的字段放最前面,排序(Sort)条件放中间,范围(Range)匹配的字段放最后面,同样适用于ES,ER。 - 每一个查询都必须要有对应的索引 - 尽量使用覆盖索引 Covered Indexes(可以避免读数据文件) - 需要查询的条件以及返回值均在索引中 - 使用 projection 来减少返回到客户端的的文档的内容 - 尽可能不要计算总数,特别是数据量大和查询不能命中索引的时候 - 避免使用skip/limit形式的分页,特别是数据量大的时候 ## Mongodb索引类型 ##### 1. _id索引 绝大多数集合默认建立索引,对于每个插入的数据,MongoDB都会生成一条唯一的_id字段。 ##### 2. 单键索引 例如一条记录形式为:{x:1,y:2,z:3},只要在x字段上建立索引之后,就可以用x为条件进行查询 ```shell db.demo_admin2.ensureIndex({x:1}) # 创建索引 db.demo_admin2.find({x:1}); # 使用索引查询 ``` ##### 3. 多键索引 >多键索引与单键索引区别在于多键索引的值具有多个记录,是一个数组 ```shell db.demo_admin2.insert({x:[1,2,3,4]}) ``` ##### 4. 复合索引 >当查询条件为多个时,需要建立复合索引 ```shell db.demo_3.ensureIndex({x:1,y:1}) # 1升序,-1降序 db.demo_admin2.find({x:1,y:2}) ``` ##### 5. 过期(TTL)索引 >指在一段时间后会过期的索引,此索引过一段时间会过期,索引过期后,相应的数据会被删除,适合存储一些在一段时间之后会失效的数据,比如用户登录信息,这样就不需要用到session了。 - 5.1 创建过期索引 建立索引的时候需要多用一个参数,指定索引的有效时间——expireAfterSeconds,单位为秒 ```shell db.demo_3.ensureIndex({time:1},{expireAfterSeconds:10}) ``` - 5.2 过期索引限制 - 过期索引字段值必须是指定的时间类型,必须是ISODate或ISODate数组,不能使用时间戳,否则不能被自动删除。 - 如果指定了ISODate数组,则按照最小的时间进行删除。 过期索引不能是复合索引。 - 删除时间不是精确的,删除过程是由后台程序每60s跑一次,而且删除也需要一些时间,所以存在误差。 ```shell db.demo_3.ensureIndex({time:1},{expireAfterSeconds:30} db.demo_3.insert({time:new Date()}); ``` ##### 6. 全文索引 - 6.1 全文索引创建 >全文索引创建方法与创建单键索引、复合索引类似。value换成'text',$**匹配集合下所有 ```shell ##为一个字段创建全文索引 db.articles.ensureIndex({key:"text"}) ##为多个字段创建全文索引 db.articles.ensureIndex({key_1:"text"},{key_2:"text"}) ##为集合中所有的字段创建全文索引 db.articles.ensureIndex({"$**":"text"}) ``` - 6.2 实例 ```shell db.article.ensureIndex({"article":"text"}) db.articles.find({$text:{$search:"coffee"}}) db.articles.find({$text:{$search:"aa bb cc"}}) # 包含aa或bb或cc的数据 db.articles.find({$text:{$search:"aa bb -cc"}}) # 同时包含aa、bb且不包含cc的数据 db.articles.find({$text:{$search:"\"aa\" \"bb\" \"cc\""}})# 同时包含aa、bb、cc的数据(用""包裹起来,引号需要用反斜杠\转义) ``` - 6.3 mongodb相似度查询 ```shell $meta操作符:{score:{$meta:'textScore'}} ``` 查询结果的相似度,搜索出的结果会多出一个score字段,这个得分越高,相关度越高。 ```shell db.article.find({$text:{$search:"aa bb ff"}},{score:{$meta:"textScore"}}) ``` 加上.sort方法可排序 ```shell db.article.find({$text:{$search:"aa bb ff"}},{score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}}) ``` - 6.4 全局索引的限制 - 每次查询,只能指定一个$text查询 - $text查询不能出现在$nor查询中 - 查询中如果包含了$text, hint不再起作用 - MongoDB全文索引还不支持中文 ##### 7.部分索引 >3.2版本才支持该特性,给符合条件的数据文档建立索引,意在节约索引存储空间与写入成本 ```shell db.user.createIndex({sns.qq.openId:1}) ##给qq登录openid加索引,系统其实只有很少一部分用到qq登录 ,然后才会存在这个数据字段,这个时候就没有必要给所有文档加上这个索引,仅需要满足条件才加索引 db.user.createIndex({sns.qq.openId:1} ,{partialFilterExpression:{$exists:1}}) ``` ##### 8.稀疏索引 稀疏索引仅包含具有索引字段的文档条目,即使索引字段包含空值也是如此。 索引会跳过缺少索引字段的所有文档。 ```shell db.user.createIndex({sns.qq.openId:1} ,{sparse:true}) ``` >注:3.2版本开始,提供了部分索引,可以当做稀疏索引的超集,官方推荐优先使用部分索引而不是稀疏索引。 ##### 9.地理位置索引 - 2d索引,用于存储和查找平面上的点 - 2dsphere索引,用于存储和查找球面上的点
顶部
收展
底部
[TOC]
目录
MongoDB索引与优化
相关推荐
MongoDB教程
MongoDB进阶
PHP操作MongoDB
MongoDB用户及安全