首页 > 数据库 >MongoDB索引操作和执行计划Explain()详解

MongoDB索引操作和执行计划Explain()详解

时间:2023-08-11 16:00:16浏览次数:42  
标签:1.0 MongoDB Explain db 查询 索引 详解 type id

一、索引操作

说明,下面的内容举例时,以"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方法做说明解释。

 

标签:1.0,MongoDB,Explain,db,查询,索引,详解,type,id
From: https://www.cnblogs.com/zaoyu/p/17623197.html

相关文章

  • JAVA 内存详解 (理解 JVM 如何使用 Windows 和 Linux 上的本机内存)
    级别:中级AndrewHall ,软件工程师,IBM2009年5月11日Java™堆耗尽并不是造成 java.lang.OutOfMemoryError 的惟一原因。如果本机内存 耗尽,则会发生普通调试技巧无法解决的 OutOfMemoryError 。本文将讨论本机内存的概念,Java运行时如何使用它,它被耗......
  • 2022最全Hbuilder打包成苹果IOS-App的详解
    本文相关主要记录一下使用Hbuilder打包成苹果IOS-App的详细步骤。介绍一下个人开发者账号:再说下什么是免费的苹果开发者账号,就是你没交688年费的就是免费账号,如果你想变成付费开发者账号,提交申请付费就行,账号都是一样的账号。没有账号的点击链接申请:苹果开发者账号申请登录开发者......
  • 如何将你的iOS应用成功上架App Store(图文详解)
    上架基本需求资料1、苹果开发者账号(如还没账号先申请-苹果开发者账号申请教程)2、开发好的APP通过本篇教程,可以学习到ios证书申请和打包ipa上传到appstoreconnect.apple.com进行TestFlight测试然后提交审核的完整流程!上架AppStore审核分7步进行。1、安装iOS上架辅助软件Appuploade......
  • keepalived安装及配置文件详解
    一、安装Keepalived服务两种安装方式:(1)yum方式安装yum-yinstallkeepalived#查看安装路径rpm-qlkeepalived(2)源码安装1)安装依赖yum-yinstallgccopenssl-devellibnfnetlink-devel2)下载源码wgethttps://www.keepalived.org/software/keepalived-1.4.5.tar.......
  • Java单例模式详解
    Java单例模式详解单例模式是设计模式中的一种,它确保某一个类只有一个实例,并提供一个全局点来访问这个实例。这在某些场景中是非常有用的,例如,配置管理、线程池、缓存、日志对象等。1.单例模式的基本原则:构造函数是私有的。有一个私有静态变量来保存类的唯一实例。有一个公有静态方......
  • Vue进阶(幺肆捌):Vuex 辅助函数详解
    (文章目录)一、前言一般情况下,如果需要访问vuex.store中state存放的数据,需要使用this.$store.state.属性名方式。显然,采取这样的数据访问方式,代码略显繁杂,辅助函数为了解决繁杂行问题应运而生。二、辅助函数通过辅助函数mapGetters、mapState、mapActions、mapMutations,把vuex.......
  • 一文详解自然语言处理两大任务与代码实战:NLU与NLG
    自然语言处理(NLP)涵盖了从基础理论到实际应用的广泛领域,本文深入探讨了NLP的关键概念,包括词向量、文本预处理、自然语言理解与生成、统计与规则驱动方法等,为读者提供了全面而深入的视角。作者TechLead,拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕,复旦......
  • 动态规划算法详解
    dp详解dp详解_不怕困难的博客dp模板C++动态规划模板汇总大全_不怕困难的博客......
  • centos 安装下载mongodb数据库
    mongodb下载安装官网:https://www.mongodb.com/try/download/communitytar-zxvfmongodb-linux-x86_64-rhel70-4.4.17.tgzmvmongodb-linux-x86_64-rhel70-4.4.17/usr/local/mvmongodb-linux-x86_64-rhel70-4.4.17/mongodbcd/usr/local/mongodbmkdirdatalogscd......
  • 后缀数组C++详解
    后缀定义“后缀i”代表以第i个字符开头的后缀,存储是用i代表字符串s的后缀s[i...n]后缀数组是什么?后缀数组(SuffixArray)主要关系到两个数组:sa和rk。其中,sa[i]表示将所有后缀排序后第i小的后缀的编号,也是所说的后缀数组,后文也称编号数组sa;rk[i]表示后缀i的排名,是重要......