Linux最全DBA技术栈MongoDB 索引创建和查询优化_db(3),2024年最新Linux运维常见面试题知乎

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前在阿里

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上运维知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以点击这里获取!


#### 2.2.2 索引和查询优化


索引是个与数据存储和査询相关的古老话题,目的只有一个:“提高数据获取的性能”。**我们知道一本书的前面几页肯定会有一个目录,这个目录式的索引能使我们快速査询想看的内容**。**索引保存在哪里,是个什么样的数据结构**,计算机领域的索引无外乎也是这两个主题。  
![image.png](https://img-blog.csdnimg.cn/img_convert/b8e938db6cfedfde7283ac508fba1240.png)  
 数据库保存记录的机制是建立在文件系统上的,索引也是以文件的形式存储在磁盘上,在数据库中用到的最多的索引结构就是B树。尽管索引在数据库领域是不可缺少的,但是对一个表建立过多的索引也会带来一些问题,索引的建立要花费系统时间,同时索引文件也会占用磁盘空间。  
 \*\*索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。\*\*扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。   
 索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构。  
 MongoDB索引的数据结构也是B+树,它能存储一小部分集合的数据,具体来说就是存储集合中建有索引的一个或多个字段的值,而且按照值的升序或降序排列。对于一个查询来说,如果存在合适的索引,MongoDB能够利用这个索引减少文档的扫描数量。  
如图所示查询低于30岁的用户,不用去扫描全部文档,通过索引快速返回结果,这样查询的效率是很高的。  
![image.png](https://img-blog.csdnimg.cn/img_convert/989b210e445a6a573f253fe72193fd51.png)  
 


##### 单字段索引


MongoDB默认为所有集合都创建了一个\_id字段的单字段索引,而且这个索引是唯一的,不能被删除,\_id字段作为一个集合的主键,值是唯一的,对于一个集合来说,也可以在其他字段上创建单字段的唯一索引。  
 创建单一键索引:db.collection.createIndex( { : } ),其中 是你要创建索引的字段名, 是索引类型,例如:1(升序)或 -1(降序)。  
 


###### 插入数据



for(var i = 1;i < 10;i++) db.custoners.insert({name:“zhangsan”+i,province:“liaoning”})
for(var i = 1;i < 10;i++) db.customers.insert({name:“lisi”+i,province:“fujian”})
for(var i = 1;i < 10;i++) db.customers.insert({name:“niuer”+i,province:“guangdong”})
for(var i = 1;i < 10;i++) db.customers.insert({name:“wangwu”+i,province:“Hunan”})
for(var i = 1;i < 10;i++) db.customers.insert({name:“liyi”+i,province:“Sichuan”})


![image.png](https://img-blog.csdnimg.cn/img_convert/0148bb5cf40df7883b01c98b592f235f.png)  
 


###### 创建索引


建立单字段唯一索引或者去掉{unique:true}选项就是一个普通的单字段索引  
db.customers.createIndex({name:1},{unique:true})


**1表示升序创建索引,-1表示降序创建索引。**


![image.png](https://img-blog.csdnimg.cn/img_convert/79043bacf7cc1dad866267747b18a5d4.png)



###### **通过explain查看执行计划**


MongoDB中的explain()方法用于显示查询执行计划,它可以帮助我们了解MongoDB如何执行一个查询。  
执行explain()方法后,MongoDB将返回一个对象,该对象描述了查询执行的过程,包括查询的阶段、输入输出、使用的索引等信息。  
这个对象通常包含以下字段:


1. **stages**:查询执行的阶段列表,每个阶段描述了查询的一部分执行过程。
2. **input**:查询输入的文档数量。
3. **output**:查询输出的文档数量。
4. **millis**:查询执行的时间(毫秒)。
5. **executionStats**:更详细的执行统计信息。


其中,stages字段是最重要的,它描述了查询从开始到结束的所有阶段。每个阶段都有一个**type**字段,描述了这个阶段的类型,比如:


* **COLLSCAN**:扫描整个集合。
* **IXSCAN**:扫描索引。
* **SHARD\_MERGE**:合并从多个分片返回的结果。


**通过查看stages字段,我们可以了解查询使用了哪些索引,是否有更好的优化方案等。**  
需要注意的是,explain()方法返回的结果包含了大量的详细信息,对于普通用户来说可能比较难以理解。通常我们只需要关注stages字段,以及其中的type值为**IXSCAN**的阶段,因为这是查询执行的关键阶段。


没走索引查询,查询使用了COLLSCAN阶段扫描了整个集合,但是并没有使用到索引。  
![image.png](https://img-blog.csdnimg.cn/img_convert/61274789b7a2c368f6492168a48ec587.png)


命中索引进行查询  
![image.png](https://img-blog.csdnimg.cn/img_convert/59fc1726d1bcc44efbdd244e196dc4c9.png)



##### 复合索引


创建复合索引:db.collection.createIndex( { : , : } ),其中 和 是你要创建索引的字段名, 和 是索引类型,  
例如:1(升序)或 -1(降序)。  
请注意,创建索引可能需要一些时间,具体取决于你的数据量及系统性能。同时,创建过多的索引可能会对写入性能产生负面影响,因此需要谨慎考虑。  
![image.png](https://img-blog.csdnimg.cn/img_convert/90516e18720227fac13939ce0fa3f791.png)



db.customers.find({“name” : “liyi6”, “province” : “Sichuan”}).explain()
{
“explainVersion” : “1”,
“queryPlanner” : {
“namespace” : “sample_mflix.customers”,
“indexFilterSet” : false,
“parsedQuery” : {
KaTeX parse error: Expected '}', got 'EOF' at end of input: …me" : { "eq” : “liyi6”
}
},
{
“province” : {
KaTeX parse error: Expected 'EOF', got '}' at position 22: …"Sichuan" }̲ } ] }…db” : “sample_mflix”
},
“serverInfo” : {
“host” : “13727b89dec5”,
“port” : 27017,
“version” : “5.0.5”,
“gitVersion” : “d65fd89df3fc039b5c55933c0f71d647a54510ae”
},
“serverParameters” : {
“internalQueryFacetBufferSizeBytes” : 104857600,
“internalQueryFacetMaxOutputDocSizeBytes” : 104857600,
“internalLookupStageIntermediateDocumentMaxSizeBytes” : 104857600,
“internalDocumentSourceGroupMaxMemoryBytes” : 104857600,
“internalQueryMaxBlockingSortMemoryUsageBytes” : 104857600,
“internalQueryProhibitBlockingMergeOnMongoS” : 0,
“internalQueryMaxAddToSetBytes” : 104857600,
“internalDocumentSourceSetWindowFieldsMaxMemoryBytes” : 104857600
},
“ok” : 1
}



##### 数组的多键索引


注意,创建索引可能需要一些时间,具体取决于你的数据量和系统性能。同时,创建过多的索引可能会对写入性能产生负面影响,因此需要谨慎考虑。  
**tags 的数组字段为例,展示多键索**



for(var i = 1;i < 10;i++) db.ccustomers.insert({name:“liyi”+i,“tags”: [“sports”, “music”, “movies”]})
WriteResult({ “nInserted” : 1 })
for(var i = 1;i < 10;i++) db.ccustomers.insert({name:“liyao”+i,“tags”: [“sports”, “movies”,“games”,“read”]})
WriteResult({ “nInserted” : 1 })
for(var i = 1;i < 10;i++) db.ccustomers.insert({name:“lisi”+i,“tags”: [“sports”, “music”, “movies”]})
WriteResult({ “nInserted” : 1 })
for(var i = 1;i < 10;i++) db.ccustomers.insert({name:“liyiyi”+i,“tags”: [“sports”, “movies”,“write”]})
WriteResult({ “nInserted” : 1 })
db.ccustomers.createIndex({“tags”:1})
{
“numIndexesBefore” : 1,
“numIndexesAfter” : 2,
“createdCollectionAutomatically” : false,
“ok” : 1
}


explain  
![image.png](https://img-blog.csdnimg.cn/img_convert/05df981e7bc25a26c6d3f88955713bf8.png)


查询结果  
![image.png](https://img-blog.csdnimg.cn/img_convert/753e165d6534894d17ba5050f83b5871.png)



##### 查询优化


MongoDB查询优化的方法主要有以下几点:


**先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前在阿里**

**深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年最新Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。**
![img](https://img-blog.csdnimg.cn/img_convert/14307e07828dfe59dee723f2366ac2de.png)
![img](https://img-blog.csdnimg.cn/img_convert/53c2d9e7880d9ab53fa29108bc6b0586.png)
![img](https://img-blog.csdnimg.cn/img_convert/d427c07b00cf70304ac31065cf7b3bf5.png)
![img](https://img-blog.csdnimg.cn/img_convert/7d3aaf922c32d9e1e84408bbe3c0c142.png)
![img](https://img-blog.csdnimg.cn/img_convert/1fa161d24d69f84d80539c0dbe38ec06.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上运维知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/topics/618542503)**

385566)]
[外链图片转存中...(img-n8gs9LXf-1714925385566)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上运维知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/topics/618542503)**

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值