我叫Mongo,干了「索引探索篇」提升我的效率,值得您拥有

这是mongo第四篇”索引探索”,后续会连续更新4篇

mongodb的文章总结上会有一系列的文章,顺序是先学会怎么用,在学会怎么用好,戒急戒躁,循序渐进,跟着我一起来探索交流。通过上三篇的介绍,我相信大家对我在使用上已经很溜啦,但是在实际使用中还需要注重效率提升,本文章探索索引,就是为提升效率为出发点,本文的介绍顺序是:索引简介->索引原理->索引类型->索引与查询结合使用->小结,让我们一起来一步一步的探索吧。​

01

索引简介

Mongodb的索引和其它关系型数据库索引很类似,索引是一个存储结构,其存储的内容是数据文档持久化的位置信息。一个数据集合和一本书来对比,那么索引就是书对应的目录,其作用就是加快查询效率。索引在加快查询效率的同时,在更新、删除、新增数据时也会影响数据变更效率,因为每一次数据变更都会更新一次索引。所以在索引使用时也需要慎重。

Mongodb索引的基本命令包括:

新增索引:createIndex({字段:排序方式},{可选参数})

删除索引:dropIndex({字段:排序方式})

查看索引:getIndexes()

先不管索引为什么能够提高查询效率,降低数据变更效率,先来一个实例。为了体现效果,这次我整的有点狠,直接初始化了300多万条数据,演示步骤如下:

数据初始化:

sql;gutter:true; for(var i=0;i</p> <pre><code> // 上面的数据有一个特点age的值就10个,from的值有10000个。下面分别对两个字段加上索引,并通过实际的执行语句来看效果。 </code></pre> <p>给user表的age添加一个索引(age升序)</p> <p>db.user.createIndex({age:1})</p> <p>给user表的from添加一个索引(from升序)</p> <p>db.user.createIndex({from:1})</p> <pre><code> ![我叫Mongo,干了「索引探索篇」提升我的效率,值得您拥有](https://johngo-pic.oss-cn-beijing.aliyuncs.com/articles/20230605/381957-20201215092401875-305162610.png) 其实我们都知道索引能够提高查询效率,估计很少亲自测试一把,通过测试是不是有一种爽歪歪的感觉。根据实际操作结果我们先得出几点小小的结论: * **当字段的值是有限的一些值时,其实有无索引对效率无影响;** * **当字段的值重复数据少时,索引的查询效率明显提高几百倍;** * **当查询结果需要排序时,有索引比没索引的效率高50倍左右;** * **当更新时,有索引的效率低于无索引;** * **所以在添加索引时针对字段值是有限的值时,就没必要添加索引,当经常需要用于排序的字段可以考虑添加索引。* **以上的几个结论,也是我通过实际数据操作得出的,如果有不准确的地方,希望指点改正,谢谢!** 先把结论得到这儿,下面我们在一步一步的剖析索引。 **02** **索引原理** Mongdb数据通过存储引擎持久化以后,其实在磁盘中就是一个一个的文件,每一个文件都对应一个位置信息。索引就是这一些文件位置信息与索引字段值的对应关系的有序数据集合,索引采用btree的结构持久化存储。在创建索引后,数据在查询的时,直接索引数据集合查询,然后在根据对于的位置信息操作对应的数据详情,避免了全表扫描,同时查询出的数据本来就是有序的数据,也避免了因为排序导致的性能损失。 这样我们就不难理解上面得出的几点结论了:因为索引查询避免了全表数据扫描,所有查询效率高;因为索引本身就已经是有序的数据,所以根据索引字段排序效率明显提高;因为索引会单击存储,一旦数据有变更,都需要同时更新索引数据,所有数据更新时有索引的效率低,同时索引也会增加额外的存储开销。 **03** **索引类型** MongoDB支持多种类型的索引,包括单字段索引、复合索引、多key索引、文本索引等,每种类型的索引有不同的使用场合。 **单字段索引:** 单字段索引其实很好理解,文章开始我们创建的实例就是单字段索引,简单的所说就是针对某一个字段创建一个索引,达到提高索引字段的查询效率。Mongdb默认_id字段创建单字段唯一索引。 ;gutter:true;
格式:db.collectionName.createIndex({索引字段:1升序-1降序} )

  实例:对集合user的字段age添加升序索引

  db.user.createIndex({age:1})

复合索引:

复合索引是针对单字段索引的升级版,复合索引就是联合多个字段创建索引,也是我们常说的联合索引。复合索引在数据存储上,首先根据第一字段排序、然后当第一字段值相同时在以第二字段排序、依次类推第N字段。复合索引能够满足以下两个场景的查询需要:根据复合索引多个字段组合查询;根据所有前缀字段查询,也就是所有字段的顺序的第一个至第N个的前缀字段查询。

sql;gutter:true; 格式:db.collectionName.createIndex({索引字段1:排序, 索引字段2:排序} )</p> <p>实例:对集合user添加字段from降序、age升序索引</p> <p>db.user.createIndex({from:-1,age:1 })</p> <p>以下情况可以使用到索引:</p> <p>db.user.find({from:20,age:8})、db.user.find({from:20})</p> <p>以下情况不能使用索引:</p> <p>db.user.find({age:8,from:20})、db.user.find({age:8})</p> <pre><code> 根据复合索引的使用情况得出以下几点小结论: * **索引使用顺序一定要和索引创建顺序保持一致;** * **当索引字段不完全组合查询时,需要前序字段连续;** * **创建索引时最好取值丰富的字段在前。* **多key索引:** 多key索引是指创建的索引字段为数组,多key索引会为数组的每个元素建立一条索引,使用场景就是针对字段值是数组的查询。有了前面的基础,这一个就很好理解,就不在详细描述了。 **文本索引:** 文本索引,简单的说就是针对文本数据创建索引,比如,文章信息表,如果需要根据文章关键词检索,那么就可以对文章字段创建文本索引。格式为:db.collectionName.createIndex({索引字段1: "text" } ) **04** **索引额外属性说明** createIndex创建索引时,该方法有两个参数,第一个参数就是索引字段,上面已经说了,第二个参数就是索引的额外属性,下面我们就说说索引额外属性信息。索引额外属性包括:唯一索引、TTL索引、稀疏索引。 **TTL** **索引** **:** </code></pre> <p>TTL索引属性是修饰当文档存储自定时间,当超出指定时间后,数据被被自动删除,使用场景为数据只存储指定时间,如:日志数据,关键词为expireAfterSecs,格式为:db.collectionName.createIndex({索引字段1: "text" }, {"expireAfterSecs": 失效时间单位为秒})。</p> <pre><code> TTL索引几点注意事项: * **TTL** **只使用于时间字段** * **TTL** **不使用于联合索引** * **TTL** **如果对于索引值是数组,那么只要其中一个值满足要求就自动删除* **唯一索引 (unique index)** **:** </code></pre> <p>保证索引对应的字段不会出现相同的值,比如_id索引就是唯一索引。格式为:db.collectionName.createIndex({索引字段1: "text" }, {"unique": true})。</p> <pre><code> **部分索引 (partial index)** **:** 只针对符合某个特定条件的文档建立索引,3.2版本才支持该特性。关键词为 **partialFilterExpression**, ;gutter:true;
格式为:db.collectionName.createIndex({索引字段1: "text" }, {"partialFilterExpression": {数据满足条件表达式}})。

  比如:对表user只有age=9的数据创建索引

  db.user.createIndex({age:1},

  {"partialFilterExpression":{age:9}})

稀疏索引(sparse index) :

只针对存在索引字段的文档建立索引,可看做是部分索引的一种特殊情况。关键词为:sparse,格式为:db.collectionName.createIndex({索引字段1: "text" }, {"sparse": true})。

undefined

06

索引优化( profiling

其实我们在建集合的时候,很多时候最开始是不知道那一些字段需要添加索引,是需要根据后续的实际使用场景来动态创建,那么这就会有一个问题,如果监控哪一些字段需要添加或是删除索引,可通过检测每一次操作结果的响应时间长短来动态创建索引,mongdb提供了一个profiling来动态检测执行响应情况。

MongoDB支持对DB的请求进行profiling,目前支持3种级别的profiling。

  • 0: 不开启profiling
  • 1: 将处理时间超过某个阈值(默认100ms)的请求都记录到DB下的system.profile集合 (类似于mysql、redis的slowlog)
  • 2: 将所有的请求都记录到DB下的system.profile集合(生产环境慎用)

通常,生产环境建议使用1级别的profiling,并根据自身需求配置合理的阈值,用于监测慢请求的情况,并及时的做索引优化。

sql;gutter:true;
开启profiling命令:db.setProfilingLevel(1,120 );
查询profil记录信息:db.system.profile.find()

最终通过查询出来的记录信息,对索引进行优化。

07

小结

Mongdb在提升查询效率上是很有帮助,但是在实际使用中也不要滥用,否则会适得其反,下面总结几点,供参考:

  • 索引创建时最好作用于取值丰富的字段,有限值的字段就没必要添加索引;
  • 经常排序的字段,可以考虑添加索引;
  • 一个集合中索引的个数不是越多越好,需要根据实际情况来定;
  • 执行接口慢,有可能是缺少索引(查询慢),也有可能是索引使用不当(编辑慢);
  • 复合索引在使用时,一定要结合索引字段的顺序使用。
  • END
    我叫Mongo,干了「索引探索篇」提升我的效率,值得您拥有

Original: https://www.cnblogs.com/xiaoXuZhi/p/xyh_mongoDb_Indexes.html
Author: 程序员修炼之旅
Title: 我叫Mongo,干了「索引探索篇」提升我的效率,值得您拥有

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/613015/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 6.22(js–>案例应用)

    (练习1)简易计算器: <html lang="en"> <head> <meta charset="UTF-8&quo…

    Linux 2023年6月7日
    0117
  • 一文解读:CSS语法、注释、使用方式、选择器。

    写在开篇 html的内容,想要改变它的样式?比如颜色、字体、布局,等等,怎么破?CSS代码带你起飞! css语法 css的语法非常简单,如下: 选择器 {属性: 值;属性:值} 例…

    Linux 2023年6月7日
    078
  • springboot整合redis的发布订阅模式

    所谓发布订阅模式,就是发布了消息丢到通道中,消费者进行消费 看代码: 1 首先需要配置这个连接工厂 ,这地方可能有人有疑问,为什么需要单独做一个类呢,是由与这个连接工厂其他地方需要…

    Linux 2023年5月28日
    0111
  • 如何提高团队开发质量

    年轻的时候去面过一个相对于当时我的比较高端的管理岗位,当时的我情况是,开发经验相对丰富, 但管理经验还欠缺。对方当时面临一个具体的问题。 “我们最近生产上,出现了一个比…

    Linux 2023年6月13日
    086
  • Windows Server OS 系列安装

    Windows Server OS 系列安装 Windows Server 2003 Windows Server 2008 Windows Server 2012 Windows…

    Linux 2023年6月13日
    093
  • C语言基本语法

    C语言以分号代表一条语句结束,一条命令可以在多行显示 对于空格没有多大要求,只是为了代码美观,方便看懂,但python语法就比较严格必须要加空格 注释VS快捷键Ctrl+K,然后C…

    Linux 2023年6月8日
    0100
  • 安装 Ubuntu 20.04 之后要做的事(持续更新中)

    以 Ubuntu 20.04 LTS 为例,在安装完操作系统后,应进行以下操作,以方便我们日常的工作。 1. SSH 远程登录相关设置 安装 Ubuntu 操作系统之后,首先应该按…

    Linux 2023年5月27日
    095
  • TELE poj1155 题解

    很明显,这道题是以1为根的树,存在最优子问题,因此考虑树形DP。 先看一下样例 常识:利润=收入-成本,也就是:叶节点点权-边权 那么更加明显用dp[i][j]来记录在以i为根节点…

    Linux 2023年6月6日
    0103
  • Sharding-jdbc + Seata + Nacos整合

    前置条件 先了解Sharding-jdbc、Seata、Nacos这三样东西各自的作用以及单独使用时的配置。 如果已经做过Seata + Nacos的整合的,直接看最后的 Seat…

    Linux 2023年6月7日
    0111
  • 在Windows下使用CodeBlock使用libiconv第三方库

    在 Windows 下使用 CodeBlock 使用 libiconv 第三方库 1、 选择在Project—>Build options下: 2、 如下图添加libicon…

    Linux 2023年6月6日
    096
  • Shell grep 命令扩展增强

    背景: 线上排查问题需要找出有某个特征的日志,并获取这些日志的完整调用日志链路。 比如, 通过某个tag 获取到了这些日志的 请求id 【Span ID】, 然后还需要再一步取得所…

    Linux 2023年5月28日
    093
  • canal-1.1.5实时同步MySQL数据到Elasticsearch

    一、环境准备 1、jdk 8+ 2、mysql 5.7+ 3、Elasticsearch 7+ 4、kibana 7+ 5、canal.adapter 1.1.5 二、部署 一、创…

    Linux 2023年6月13日
    0110
  • cobbler

    cobbler 1. cobbler简介 2. cobbler服务端部署 cobbler简介 Cobbler是一个Linux服务器安装的服务,可以通过网络启动(PXE)的方式来快速…

    Linux 2023年6月7日
    085
  • Flink 集群搭建,Standalone,集群部署,HA高可用部署

    基础环境 准备3台虚拟机 配置无密码登录 配置方法:https://ipooli.com/2020/04/linux_host/ 并且做好主机映射。 https://www.apa…

    Linux 2023年6月7日
    0125
  • fastdfs集群部署

    fastdfs集群部署 参考链接:https://www.cnblogs.com/penngke/p/15396701.html部署架构如下: 部署规划 2台主机,数据存储节点共1…

    Linux 2023年6月8日
    0110
  • MySQL实现 group_concat 排序

    MySQL支持实现group_concat() 内部自定义排序: 实例: 新建一张表 reward,表中数据如下: SQL: SELECT uid, GROUP_CONCAT(mo…

    Linux 2023年6月13日
    0121
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球