一、索引操作

说明,下面的内容举例时,以"dailyTrip"collection为例。 字段内容如下:

{
"_id" : ObjectId("63ec5a971ddbe429cbeeffe3"), // object id
"car_type" : "Gett", // string
"date" : ISODate("2016-04-01T00:00:00.000+0000"), //ISODate
"trips" : 0.0, // number
"monthly" : "NA", // string
"parent_type" : "Ride-hailing apps", // string
"monthly_is_estimated" : true, // boolean
"geo" : { // object
"$concat" : [ // array
"$parent_type",
"$grouping"
]
}
}

执行看看有5.17万条数据

1. 索引类型

  • 单列索引: 在一个字段上创建的索引。

  • 复合索引:由多个字段组合一起创建的索引。使用的时候要注意最左前缀原则,避免索引无法命中(失效)。

  • 文本索引(全文索引)和空间索引(GEO索引),不常用,这里不讲,具体自行网上查询。

2. 查看

语法:

db.Collection.getIndexs(); 

返回内容说明:

[  // 返回一个数组,内容是所有索引
{
"v" : 2.0, // 索引版本,可忽略
"key" : { // 索引加在哪个字段,以及排序
"_id" : 1.0 // _id 是字段, 1.0是正序(升序), -1.0是倒序(倒序)
},
"name" : "_id_" // 索引名,如果添加的时候没有指定,Mongo会自动生成。
}
]

举例:

可以看到返回一个name为 _id_的索引。 作用于 _id上, 升序排列。

3. 创建

语法:

db.collection.createIndex(keys, options)

// 组合索引
db.collection.createIndex( { <field1>: <type>, <field2>: <type2>, ... } ) // 其中 <fieldN>是字段名 <typeN>是排序 注意:3.0.0 版本之前创建索引方法为 db.collection.ensureIndex()。 5.0之后ensureIndex() 已被移除。

举例:

// 创建单字段索引
db.dailyTrip.createIndex({"car_type":1}); // 返回结果
{
"numIndexesBefore" : 1.0, // 新建索引前的索引数
"numIndexesAfter" : 2.0, // 新建索引后的索引数
"createdCollectionAutomatically" : false, // 一般情况下,如果该集合存在,这里就是返回false。如果指定的集合不存在,MongoDB 默认情况下会自动创建该集合,并在该集合上创建索引,此时返回true。
"ok" : 1.0 // 创建结果 1.0则是成功。返回0则说明报错了。
} // 如果创建的字段的索引已经存在,则返回如下
{
"numIndexesBefore" : 2.0,
"numIndexesAfter" : 2.0,
"note" : "all indexes already exist", // 提示已经存在
"ok" : 1.0
} // 创建复合索引
db.dailyTrip.createIndex({"parent_type":1, "car_type":1})
// 也可以指定自定义索引名
db.dailyTrip.createIndex({"parent_type":1, "car_type":1}, { name: "inx_parantType_carType" }) // 这里自己试验 // 来自官方文档 https://www.mongodb.com/docs/manual/reference/command/createIndexes/

创建完毕后,再次查看当前索引情况

4. 删除

语法:

删除指定集合中所有索引:
db.collection.dropIndexes();
删除指定集合中的具体索引:
db.collection.dropIndex("索引名称");

举例:

// 删除指定索引
db.dailyTrip.dropIndex("car_type_1"); // 返回结果
{
"nIndexesWas" : 3.0, // 指示在删除索引之前集合中存在的索引数量。
"ok" : 1.0
} // 删除所有,自行尝试。 注意, 主键_id的索引是不会也不能被删除的。
db.collection.dropIndexes();

5. 修改

无法直接修改,如果需要调整索引字段、名称、组合索引的顺序,需要先删除原来索引,再新建索引。

6. 索引使用原则

  1. 选择经常被查询的字段来创建索引。那些在查询条件、排序和聚合操作中频繁出现的字段是最佳选择。

  2. 选择合适的、常用作查询条件的字段,综合判断是否可以使用复合索引,如果可以优先复合索引。 比如多数情况是按照字段A、B、C或者A、B条件去查询,那么可以优先考虑基于字段A、B、C创建复合索引。 使用复合索引来覆盖多个查询条件,以减少索引的数量。

  3. 尽量使用索引覆盖,和MySQL中的索引覆盖是类似的。 覆盖索引是指索引包含了查询所需的字段,从而避免了查询需要访问实际文档。这可以提高查询性能,减少IO操作。 其实这里和上面的复合索引是相关的。

  4. 其他的还有包括使用Explain去查看执行计划、定期监控性能、删除冗余无用的索引之类的,不一而足。 上面是基于实际开发经验得出的常用手段原则。

7. 索引失效的情况

  1. 查询条件不满足索引前缀: 例如,复合索引是 { a: 1, b: 1 },而查询条件只包含 { b: 1 },则该复合索引将无法被使用。

  2. 数据类型不匹配: 如果查询条件中的数据类型与索引字段的数据类型不匹配,索引可能无法被使用。例如,如果索引字段是数字类型,而查询条件中使用了字符串类型的值,索引将无法被使用。

    // 类似Mysql中的隐式转换会使索引失效。

  3. 索引选择性低: 索引的选择性是指索引中不同值的唯一性程度。如果索引的选择性很低,即索引中的值几乎都相同,那么使用该索引可能不会带来明显的性能提升。

    // 这里其实是说索引列的值的区分度,如果重复度过高,那么使用索引的性能可能不如不用,索引底层优化器可能不选择使用索引。假如字段gender只有2个值,male和female,其中一半数据是male,另一半是female,此时用gender索引,还不如不用。

  4. 使用不支持的操作符: 某些查询操作符可能无法使用索引。例如,正则表达式查询、模糊查询(如 $text 操作符)等可能无法充分利用索引。

  5. 数据量较小: 当集合中的数据量较小时,MongoDB 可能会选择全表扫描而不使用索引,因为全表扫描可能更快。

    // 类似mysql中,一般建议小于1000条就不加索引,因为索引有额外开销。

  6. 索引过期或损坏: 如果索引过期或损坏,MongoDB 将无法使用该索引。

  7. 索引被禁用: 如果在查询时禁用了索引,或者索引的存储引擎不支持该查询,索引将无法被使用。

  8. 索引尺寸过大: 如果索引的尺寸超过了 MongoDB 的限制,该索引可能无法被使用。

使用 explain() 方法可以查看查询计划和索引使用情况,帮助识别索引失效的原因,并进行相应的优化。

接下来对Explain方法做说明解释。

MongoDB索引操作和执行计划Explain()详解的更多相关文章

  1. MySQL 执行计划explain详解

    MySQL 执行计划explain详解 2015-08-10 13:56:27 分类: MySQL explain命令是查看查询优化器如何决定执行查询的主要方法.这个功能有局限性,并不总会说出真相,但 ...

  2. MongoDB干货系列2-MongoDB执行计划分析详解(2)(转载)

    写在之前的话 作为近年最为火热的文档型数据库,MongoDB受到了越来越多人的关注,但是由于国内的MongoDB相关技术分享屈指可数,不少朋友向我抱怨无从下手. <MongoDB干货系列> ...

  3. 0912MySQL 执行计划explain详解

    转自http://blog.itpub.net/29773961/viewspace-1767044/ 该博客内容是比较全的,虽然写的比较晦涩,多读几遍还是不错的 explain命令是查看查询优化器如 ...

  4. SQL Server 执行计划操作符详解(3)——计算标量(Compute Scalar)

    接上文:SQL Server 执行计划操作符详解(2)--串联(Concatenation ) 前言: 前面两篇文章介绍了关于串联(Concatenation)和断言(Assert)操作符,本文介绍第 ...

  5. SQL Server 执行计划操作符详解(2)——串联(Concatenation )

    本文接上文:SQL Server 执行计划操作符详解(1)--断言(Assert) 前言: 根据计划,本文开始讲述另外一个操作符串联(Concatenation),读者可以根据这个词(中英文均可)先幻 ...

  6. MongoDB执行计划分析详解

    要保证数据库处于高效.稳定的状态,除了良好的硬件基础.高效高可用的数据库架构.贴合业务的数据模型之外,高效的查询语句也是不可少的.那么,如何查看并判断我们的执行计划呢?我们今天就来谈论下MongoDB ...

  7. MYSQL EXPLAIN执行计划命令详解(支持更新中)

    本文来自我的github pages博客http://galengao.github.io/ 即www.gaohuirong.cn 摘要: 本篇是根据官网中的每个一点来翻译.举例.验证的:英语不好,所 ...

  8. SQL Server 执行计划操作符详解(1)——断言(Assert)

    前言: 很多很多地方对于语句的优化,一般比较靠谱的回复即使--把执行计划发出来看看.当然那些只看语句就说如何如何改代码,我一直都是拒绝的,因为这种算是纯蒙.根据本人经验,大量的性能问题单纯从语句来看很 ...

  9. 学习计划 mysql explain执行计划任务详解

    我们在之前已经找到了需要优化的SQL,但是怎么知道它的那些方面需要优化呢? explain就是为了这个使用的. explain显示了 mysql 如何使用索引来处理select语句以及连接表.可以帮助 ...

  10. MySQL执行计划 EXPLAIN参数

    MySQL执行计划参数详解 转http://www.jianshu.com/p/7134286b3a09 MySQL数据库中,在SELECT查询语句前边加上“EXPLAIN”或者“DESC”关键字,即 ...

随机推荐

  1. 2022-07-02:以下go语言代码输出什么?A:编译错误;B:Panic;C:NaN。 package main import “fmt“ func main() { var a =

    2022-07-02:以下go语言代码输出什么?A:编译错误:B:Panic:C:NaN. package main import "fmt" func main() { var ...

  2. 2021-09-02:IP 到 CIDR。给定起始IP和整数n,返回长度最小的CIDR块。力扣751。比如:ip=255.0.0.7,n=10,输出:[“255.0.0.7/32“,“255.0.0.

    2021-09-02:IP 到 CIDR.给定起始IP和整数n,返回长度最小的CIDR块.力扣751.比如:ip=255.0.0.7,n=10,输出:["255.0.0.7/32" ...

  3. vue全家桶进阶之路2:JavaScript

    JavaScript(简称"JS")是当前最流行.应用最广泛的客户端脚本语言,用来在网页中添加一些动态效果与交互功能,在 Web 开发领域有着举足轻重的地位.JavaScript ...

  4. 【GiraKoo】面试者如何忽悠一个不懂技术的面试官

    萌新面试者如何忽悠一个不懂技术的面试官 由于公司业务需要,做了几天Android的面试官. 作为一个完全没有做过Android项目的开发者,我无法问出具体的框架,技术细节. 对于萌新,新公司,新业务往 ...

  5. ESlint配置详解

    开发中出现eslint提示代码格式错误,有时候不明白其配置规范,是件很头疼的事情到处找api又是半天:so记录一份配置详情便于开发中翻阅 { // 环境定义了预定义的全局变量. "env&q ...

  6. 让优惠再续一年!SHPC 老客专享

    最近云筏君经常收到自家小伙伴发来的关于产品活动的关心慰问,掐指一算,哦,原来是一年一度大家喜闻乐见的剁手节(学名"双十一")马上要来了! 大家都知道,云筏家的产品向来主打高性价比, ...

  7. Qt+QtWebApp开发笔记(五):http服务器html中使用json触发ajax与后台交互实现数据更新传递

    前言   前面完成了页面的跳转.登录,很多时候不刷新页面就想刷新局部数据,此时ajax就是此种技术,且是异步的.  本篇实现网页内部使用js调用ajax实现异步交互数据.  在js中使用 ajax是通 ...

  8. Atcoder-AGC033C

    看到这道题,是个博弈论,没见过树上的,于是想到在数列里的博弈论,又联想到树的特殊形式----链. 于是我们来讨论一下链的情况(对于没有硬币的点,我们就视为它被删掉了): 讨论链的情况 发现若是选择两端 ...

  9. 【HMS Core】Android Studio安装Toolkit登录报错{"httpCode":500,"errorCode":"00012005"...

    [问题描述] 在Android Studio安装Toolkit插件,安装后登录,报错 ​ ​ [问题分析] 此种情况一般是由于开发者账户未实名造成的 [解决方案] 1.检查开发者账户是否实名,登录联盟 ...

  10. Go-变量篇

    一.变量的声明方式(三种) 1.var a int = num 2.var a = num 3.a := num 二.字符类型使用细节 *Golang的字符使用UTF-8. 英文 -1 字节:汉字-3 ...