mongodb 索引
1.索引
索引是数据库中性能优化非常关键的技术,有索引和没有索引查询的效率差别非常大.
2. explain
类似于mysql数据库中的explain语句,mongodb也有explain
db.users.find({"username":"user101"}).explain("executionStats") 执行完后会显示出语句的解释信息.
totalDocsExamined是查询时查看的文档总数.
executionTimeMillis 会显示执行查询所用的毫秒数.
executionStats 的 nReturned 字段显示查找到的结果数量.
3.创建索引
db.users.createIndex({"username":1})
表示在username上创建索引,在次执行explain语句后能看到totalDocsExamined和executionTimeMillis 只有1
缺点: 索引创建后删除更新操作都会修改索引,会有额外的性能开销.
4.复合索引
在多个键上创建索引是复合索引
db.users.createIndex({"age":1,"username":1})
建议把排序键放到索引的第一个位置,这样排序效率会比较高.
5. mongodb索引的选择
在执行一个查询语句,mongodb会按照所需索引的个数创建多个线程执行任务,执行最快的被选为结果,并在后续有类似查询选择该索引.
重启,修改索引和键都会删除查询计划并重新多线程选择.
等值过滤字段排在多值字段前面也会提升效率,尽量不要用hint更改索引优先级.
索引优化总结:
等值过滤的键应该在最前面;
用于排序的键应该在多值字段之前;
多值过滤的键应该在最后面;
5.1索引的方向
db.users.createIndex({"username": -1})
如果索引参数是-1的话,索引顺序就是相反的方向.和查询方向一致可以保持效率;
只有在基于多键排序,方向才比较重要,单键排序mongodb会从相反的方向寻找.
5.2覆盖查询
当一个索引包含用户请求的所有字段,这个索引就覆盖了本次查询;
可以使用find方法第二个参数过滤掉_id字段提高速度;
5.3隐式索引
如果有{"age":1,"username":1}上的索引,那么age字段的排序方式和在{"age":1}上的索引相同;
只是前缀相同才可以,比如{"a":1,"b":1,"c":1}只有{"a":1}{"a":1,"b":1}才可以,
如果是{"a":1,"c":1}则不行;
5.4 $运算符如何使用索引
5.4.1 同 mysql数据库一样, 用$ne和$not不等于进行查询效率比较低
可以尝试另一个索引的语句,让查询集变小;
5.4.1 范围
精准查找索引在前,范围查找索引在后;
5.4.1 or
尽量使用in,or会执行两次查询,不如单次查询高;
5.4 索引对象和数组
1.索引内嵌文档
直接用字段创建就可以
db.users.createIndex({"loc.city":1})
2.索引数组
同索引内嵌文档
db.users.createIndex({"comments.data":1})
但是数组索引会为数组中的每一个元素创建索引,如果是多个索引的话,索引只能有一个是数组;
5.4 索引类型
1.唯一索引
db.users.createIndex({"comments.data":1},{"unique":true})
保证键只有一个,插入重复的值会报错;
2.部分索引
当键存在的时候才创建索引
db.users.createIndex({"comments.data":1},{"unique":true,"partialFilterExpression":{"unique":{$exists:true}}})
加上partialFilterExpression即可;
6.索引管理
1.查询索引
db.users.getIndexes();
2.标识索引
db.users.createIndex({"age":1},{"name":"alphabet"})
可以给索引命名
3.修改索引
db.users.dropIndex("alphabet")