MongoDB之索引

常用命令

查看表的索引

db.<table>.getIndexes()

查看表索引的大小

db.<table>.totalIndexSize()

重建索引

db.<table>.reIndex()

删除索引

db.COLLECTION_NAME.dropIndex("INDEX-NAME")
db.COLLECTION_NAME.dropIndexes()

_id 索引无法删除。

执行计划

参考:MongoDB干货系列2-MongoDB执行计划分析详解(1) | MongoDB中文社区、MongoDB - 执行计划 - 听雨危楼 - 博客园

-- 千万测试数据
for(var i=1;i<10000000;i++){ db.indexDemo.insert({_id:i , num:'index:'+i ,address:'address:i%9999'})}

默认的查询计划 queryPlanner

-- 不使用索引
db.indexDemo.find({num:'index:99999'}).explain()db.indexDemo.createIndex( { num: 1 } )
db.indexDemo.getIndexes()
db.indexDemo.dropIndex("num_1")
{"explainVersion" : "1","queryPlanner" : {"namespace" : "study.goods",                     【查询的表】"indexFilterSet" : false,                        【是否有indexfilter】"parsedQuery" : {                                【查询过滤条件】"qty" : {"$gt" : 50}},"queryHash" : "3DC2392F","planCacheKey" : "B7F8CFFA","maxIndexedOrSolutionsReached" : false,"maxIndexedAndSolutionsReached" : false,"maxScansToExplodeReached" : false,"winningPlan" : {                                【最优执行计划详细内容】"stage" : "FETCH",FETCH:通过返回的index扫描。COLLSCAN:全表扫描】"inputStage" : {                         【子stage】"stage" : "IXSCAN",              【表示进行索引扫描】"keyPattern" : {                 【扫描的索引内容】"qty" : 1},"indexName" : "qty_1",           【使用的索引名称】"isMultiKey" : false,            【是否多列索引。索引建立在array上时是true"multiKeyPaths" : {"qty" : [ ]},"isUnique" : false,"isSparse" : false,"isPartial" : false,"indexVersion" : 2,"direction" : "forward",         【查询的顺序:forward升序、backward降序】"indexBounds" : {                【索引扫描范围,没有制定范围就是[MaxKey,MinKey]"qty" : ["(50.0, inf.0]"]}}},"rejectedPlans" : [ ]                            【其它非最优的执行计划】},"command" : {"find" : "goods","filter" : {"qty" : {"$gt" : 50}},"sort" : {"qty" : 1},"$db" : "study"},"serverInfo" : {                                         【服务器信息】"host" : "fe9b0d04fcbd","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
}

附加执行状态 executionStats

-- 在默认的执行计划信息上,多了 executionStats 信息
db.indexDemo.find({num:'index:99999'}).explain("executionStats")
{"explainVersion" : "1","queryPlanner" : {...},"executionStats" : {"executionSuccess" : true,                     【是否执行成功】"nReturned" : 1,                               【匹配到的文档数】"executionTimeMillis" : 0,                     【选择和查询执行计划所需时间。毫秒】"totalKeysExamined" : 1,											 【扫描的索引条目数】"totalDocsExamined" : 1,                       【扫描文档数】"executionStages" : {                          【最优执行计划的完整信息】"stage" : "FETCH",FETCH:根据索引结果去扫描文档】"nReturned" : 1,                             【stage=FETCH时,跟上面的nReturned一样】"executionTimeMillisEstimate" : 0,           【检索文档获得数据的时间】"works" : 2,                                 【执行查询阶段的各个工作以“单元”划分,这里表示工作单元数】"advanced" : 1,															 【返回到父阶段的结果数】"needTime" : 0,                              【中间结果返回给父级的工作循环次数】"needYield" : 0,"saveState" : 0,"restoreState" : 0,"isEOF" : 1,"docsExamined" : 1,"alreadyHasObj" : 0,"inputStage" : {...}}},"command" : {"find" : "indexDemo","filter" : {"num" : "index:99999"},"$db" : "study"},"serverInfo" : {...},"serverParameters" : {"internalQueryFacetBufferSizeBytes" : 104857600,"internalQueryFacetMaxOutputDocSizeBytes" : 104857600,"internalLookupStageIntermediateDocumentMaxSizeBytes" : 104857600,"internalDocumentSourceGroupMaxMemoryBytes" : 104857600,"internalQueryMaxBlockingSortMemoryUsageBytes" : 104857600,"internalQueryProhibitBlockingMergeOnMongoS" : 0,"internalQueryMaxAddToSetBytes" : 104857600,"internalDocumentSourceSetWindowFieldsMaxMemoryBytes" : 104857600},"ok" : 1
}

关键参数

耗时 executionTimeMillis

  • executionStats.executionTimeMillis:整体查询时间。
  • executionStats.executionStages.executionTimeMillisEstimate:检索Document获得数据的时间
  • executionStats.executionStages.inputStage.executionTimeMillisEstimate:扫描文档 Index所用时间

扫描数 nReturned

  • nReturned:查询结果返回的条目数
  • totalKeysExamined:总索引扫描的条目数
  • totalDocsExamined :总索引扫描的条目数

扫描数越少越好,理想情况:
nReturned = totalKeysExamined = otalDocsExamined

stage 参数表

类型描述
COLLSCAN全表扫描
IXSCAN索引扫描
FETCH根据索引去检索指定document
SHARD_MERGE将各分片的返回结果合并
SORT在内存中进行了排序
LIMIT限制返回数
SKIP使用skip进行跳过
IDHACK针对_id进行的查询
SHARDING_FILTER通过mongos对分片数据进行查询
COUNT利用db.coll.explain().count()之类进行count运算
TEXT全文索引
PROJECTION限定返回字段时候

返回最优与备选计划 allPlansExecution

db.indexDemo.find({num:'index:99999'}).explain("allPlansExecution")

慢查询分析

开启内置查询分析器

-- 开启内置查询分析器
db.setProfilingLevel([0,1,2],m)
0:不记录
1:记录超过阈值m的记录
2:记录所有读写操作-- 例子
db.setProfilingLevel(1,100)
db.setProfilingLevel(2)

查看监听结果

db.system.profile.find().sort({millis:-1}).limit(3)

结果分析

慢查询常见于:

  • 应用设计不合理;
  • 数据模型不合理;
  • 硬件配置;
  • 缺少索引;

explain 分析是否跑索引

创建索引

测试数据

db.goods.insertMany( [
{ item: "canvas", qty: 100, size: { h: 28, w: 35.5, uom: "cm" }, status:
"A" },
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status:
"A" },
{ item: "mat", qty: 85, size: { h: 27.9, w: 35.5, uom: "cm" }, status:
"A" },
{ item: "mousepad", qty: 25, size: { h: 19, w: 22.85, uom: "cm" },
status: "P" },
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status:
"P" },
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status:
"D" },
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status:
"D" },
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" },
status: "A" },
{ item: "sketchbook", qty: 80, size: { h: 14, w: 21, uom: "cm" }, status:
"A" },
{ item: "sketch pad", qty: 95, size: { h: 22.85, w: 30.5, uom: "cm" },
status: "A" }
]);
db.inventory.insertMany([
{ _id: 1,item: "abc",stock: [{ size: "S", color: "red", quantity: 25 },{
size: "S", color: "blue", quantity: 10 },{ size: "M", color: "blue",
quantity: 50 }]},
{_id:2,item:"def",stock:[{size:"S",color:"blue",quantity:20},
{size:"M",color:"blue",quantity:5},{size:"M",color:"black",quantity:10},
{size:"L",color:"red",quantity:2}]},
{_id:3,item:"ijk",stock:[{size:"M",color:"blue",quantity:15},
{size:"L",color:"blue",quantity:100},{size:"L",color:"red",quantity:25}]}
])

单字段索引 Single Field

单列索引

db.<table>.createIndex(keys, options)
options:

  • 1:按照升序创建索引
  • -1:按照降序创建索引

db.indexDemo.find({num:"index:600"}).explain()db.indexDemo.createIndex({num:1})db.indexDemo.find({num:"index:600"}).explain()

给嵌入式字段创建索引

{"_id": ObjectId("570c04a4ad233577f97dc459"),"score": 1034,"location": { state: "NY", city: "New York" }
}-- 创建索引
db.<table>.createIndex( { "location.state": 1 } )-- 索引生效
db.<table>.find( { "location.state": "CA" } )
db.<table>.find( { "location.city": "Albany", "location.state": "NY" } )

给整个内嵌文档创建索引

{"_id": ObjectId("570c04a4ad233577f97dc459"),"score": 1034,"location": { state: "NY", city: "New York" }
}-- 创建索引
db.<table>.createIndex( { location: 1 } )-- 索引生效
db.records.find( { location: { city: "New York", state: "NY" } } )

复合索引 Compound Index

db.collection.createIndex( { <field1>: <type>, <field2>: <type2>, ... } )

⚠️不能创建具有hashed索引类型的复合索引。如果试图创建包含hashed索引字段的复合索引,将收到一个错误。

{"_id": ObjectId(...),"item": "Banana","category": ["food", "produce", "grocery"],"location": "4th Street Store","stock": 4,"type": "cases"
}-- 创建索引
db.<table>.createIndex( { "item": 1, "stock": 1 } )-- 索引生效
db.<table>.find( { item: "Banana" } )
db.<table>.find( { item: "Banana", stock: { $gt: 5 } } )

⚠️特别注意字段的顺序与排序。复合索引遵循最左匹配原则。

多键索引 Multikey indexes

支持对数组中每个元素创建索引。元素类型:string、number、 nested documents(嵌套文档) 。

number 类型数组

db.inventory.remove({})
db.inventory.insertMany([{ _id: 5, type: "food", item: "aaa", ratings: [ 5, 8, 9 ] },{ _id: 6, type: "food", item: "bbb", ratings: [ 5, 9 ] },{ _id: 7, type: "food", item: "ccc", ratings: [ 9, 5, 8 ] },{ _id: 8, type: "food", item: "ddd", ratings: [ 9, 5 ] },{ _id: 9, type: "food", item: "eee", ratings: [ 5, 9, 5 ] }
])
-- 没加索引
db.inventory.find({ratings:[5,9]}).explain("executionStats")
-- 给数组加索引
db.inventory.createIndex( { ratings: 1 } )

嵌套文档 类型数组

单列索引
db.inventory.dropIndexes()db.inventory.insertMany([{ type: "food", item: "aaa", ratings: [ 5, 8, 9 ], size:[{w:10,h:165},{w:9,h:158}] },{type: "food", item: "aaa", ratings: [ 5, 8, 9 ], size:[{w:11,h:175},{w:7,h:142}] },{type: "food", item: "aaa", ratings: [ 5, 8, 9 ], size:[{w:15,h:163},{w:8,h:157}] }
])
-- 无索引查询
db.inventory.find({"size.w":10}).explain("executionStats")
-- 添加索引
db.inventory.createIndex({"size.w":1})
复合索引
-- 添加复合索引
db.inventory.createIndex( {"size.w":1,"size.h":2})
-- 查询
db.inventory.find({"size.w":10}).explain("executionStats")
db.inventory.find({"size.w":10},{"size.h":10}).explain("executionStats")

地理空间索引 Geospatial Index

  • 2dsphere索引,用于存储和查找球面上的点
  • 2d索引,用于存储和查找平面上的点
db.company.insert({loc : { type: "Point", coordinates: [ 116.482451, 39.914176 ] },name:"来广营地铁站-叶青北园",category : "Parks"}
)
# 2dsphere 或者 2d 。可以建立组合索引。
db.company.ensureIndex( { loc : "2dsphere" } )db.company.find({"loc" : {"$geoWithin" : {"$center":[[116.482451,39.914176],0.05]}}
})

全文索引 Text Index

一个集合最多一个全文索引,可以覆盖多个字段。中文分词支持不佳(推荐ES)。

db.<table>.createIndex({"fieldA": "text"})db.<table>.createIndex({fieldA: "text",fieldB: "text"})db.store.insert([
{ _id: 1, name: "Java Hut", description: "Coffee and cakes" },
{ _id: 2, name: "Burger Buns", description: "Gourmet hamburgers" },
{ _id: 3, name: "Coffee Shop", description: "Just coffee" },
{ _id: 4, name: "Clothes Clothes Clothes", description: "Discountclothing" },
{ _id: 5, name: "Java Shopping", description: "Indonesian goods" }
])db.store.createIndex( { name: "text", description: "text" } )db.store.find( { $text: { $search: "java coffee shop" } } )
{ "_id" : 3, "name" : "Coffee Shop", "description" : "Just coffee" }
{ "_id" : 1, "name" : "Java Hut", "description" : "Coffee and cakes" }
{ "_id" : 5, "name" : "Java Shopping", "description" : "Indonesian goods" }

哈希索引 Hashed Index

只用于等值查询。

db.<table>.createIndex({"字段": "hashed"})

MongoDB 索引底层数据结构

文档类型数据库使用 BSON 格式保存数据,比 RDBMS 存储更方便。RDBMS 适合用于多表之间的关联的场景,而 BSON 可以把关联的数据存在一起。
比如MySQL使用 RDBMS 格式,数据的关联性强,范围查询普遍。所以底层使用B+树。
MongoDB使用B树,通过索引能更快访问,但不适合范围查询。
image.png
B树特点

  • 多路搜索。
  • 节点存储既存储索引又存储数据。
  • 关键字在树中只出现一次。

跟B+树的区别:

  • 叶子节点之间的指向。
  • 数据保存的位置。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/636438.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MCU最小系统原理图中四个问题详解——芯片中有很多电源管脚的原因(VDD/VSS/VBAT)、LC滤波、两级滤波、NC可切换元件

前言&#xff1a;本文对MCU最小系统原理图中的四个问题进行详解&#xff1a;芯片中有很多电源管脚的原因&#xff08;VDD/VSS/VBAT&#xff09;、LC滤波、两级滤波、NC可切换元件。本文以GD32F103C8T6最小系统原理图举例 目录&#xff1a; 芯片中有很多电源管脚的原因&#x…

echarts dataZoom实现左右滑动与放大缩小 并精确控制显示几条数据

//Xdata是横轴的长度&#xff08;若x轴80条数据&#xff0c;默认显示最新的20条&#xff09; var start Xdata.length - 20; var end Xdata.length - 1; dataZoom: [ type: slider, show: true, startValue: dataZoomStart, endValue: dataZoomEnd, dataBackground: { ar…

STL——list

1、list介绍 1. list 是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。 2. list 的底层是带头双向循环链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向其前一个元素和后…

CVE-2023-46226 Apache iotdb远程代码执行漏洞

项目介绍 Apache IoTDB 是针对时间序列数据收集、存储与分析一体化的数据管理引擎。它具有体量轻、性能高、易使用的特点&#xff0c;完美对接 Hadoop 与 Spark 生态&#xff0c;适用于工业物联网应用中海量时间序列数据高速写入和复杂分析查询的需求。 项目地址 https://io…

Leetcoder Day9|栈与队列part01

语言&#xff1a;Java/C 目录 理论基础 C 栈 队列 Java 栈 队列 ​编辑 232.用栈实现队列 225. 用队列实现栈 Queue Deque 今日心得 理论基础 又是考研时数据结构里接触到的老朋友&#xff0c;栈是先进后出&#xff0c;队列是先进先出。 C 现在刷题除了思路还…

力扣-202. 快乐数解析-弗洛伊德循环查找算法

题目链接 public static void Happy(int n) {int sum 0;int digit 0;for (int i 0; i < 20; i) {while (n ! 0) {digit n%10;sum digit*digit;n/10;}System.out.print(sum " ");n sum;sum 0;}} 使用代码测试一下每一代数字 n 2 : 4 16 37 58 89 145 42 …

自然语言处理(Natural Language Processing,NLP)解密

专栏集锦&#xff0c;大佬们可以收藏以备不时之需&#xff1a; Spring Cloud 专栏&#xff1a;http://t.csdnimg.cn/WDmJ9 Python 专栏&#xff1a;http://t.csdnimg.cn/hMwPR Redis 专栏&#xff1a;http://t.csdnimg.cn/Qq0Xc TensorFlow 专栏&#xff1a;http://t.csdni…

Servlet中service()与doGet() doPost() 是什么关系

Servlet&#xff08;Server Applet&#xff09;&#xff0c;全称Java Servlet。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据&#xff0c;生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口&#xff0c;广义的Servlet是指任何实现了这个Servlet…

关于去除信号中的直流分量效果演示(零频率分量)

本文作者&#xff1a; slience_me 文章目录 关于去除信号中的直流分量效果演示&#xff08;零频率分量&#xff09;1. 效果图展示&#xff1a;2. 快速傅里叶变换FFT3. 相关验证代码 关于去除信号中的直流分量效果演示&#xff08;零频率分量&#xff09; 1. 效果图展示&#x…

JDK 动态代理(Spring AOP 的原理)(面试重点)

代理模式 也叫委托模式.定义&#xff1a;为其他对象提供⼀种代理以控制对这个对象的访问.它的作⽤就是通过提供⼀个代理类,让我们 在调⽤⽬标⽅法的时候,不再是直接对⽬标⽅法进⾏调⽤,⽽是通过代理类间接调⽤&#xff0c;在某些情况下,⼀个对象不适合或者不能直接引⽤另⼀个对…

51单片机蜂鸣器

蜂鸣器 蜂鸣器的工作原理 三极管的工作原理 三极管是一种半导体器件&#xff0c;通常由三个掺杂不同的半导体材料层构成。它常用于放大和开关电路中。三极管的工作原理可简述如下&#xff1a; 放大作用&#xff1a;三极管可以放大电流和电压信号。它的工作原理基于控制一个较大…

Web前端与低代码可以碰出什么火花?

技术快速迭代&#xff0c;Web前端开发已经逐渐成为构建现代应用程序的关键组成部分。它不仅涉及到美观的界面设计&#xff0c;还包括后端功能的实现&#xff0c;以及跨平台兼容性的考虑。然而&#xff0c;传统的Web前端开发过程往往需要进行长时间的编码和调试&#xff0c;这使…

LTC6820和isoSPI使用

1、MSTR主控/受控 MSTR (引脚 11/ 引脚 12)&#xff1a;串行接口主 / 从选择器输入。MSTR接VCC&#xff0c;则LTC6820为从机&#xff1b;MSTR接GND&#xff0c;则LTC6820为主机 2、SLOW慢速/快速 SLOW (引脚 12/ 引脚 13)&#xff1a;慢速接口选择输入。当时钟频率≤ 200kHz …

C++和Python最常用的库框架一览

一、C常用库 1. 标准模板库(STL) STL包含丰富的数据结构与算法。比如vector动态数组;list双向链表;map基于红黑树实现,支持快速查找键值对。常用算法有sort排序、find搜索等。这些容器算法类和函数模板,是C程序员必不可少的基础。 2. Boost Boost是近年兴起的高质量C库集合…

网络安全:守护数字世界的盾牌

在当今数字化的时代&#xff0c;网络已经渗透到我们生活的方方面面。从社交媒体到在线银行&#xff0c;从在线购物到工作文件传输&#xff0c;网络几乎无处不在。然而&#xff0c;随着网络的普及&#xff0c;网络安全问题也日益凸显。那么&#xff0c;如何确保我们的数字资产安…

递归、搜索与回溯算法(专题一:递归)

往期文章&#xff08;希望小伙伴们在看这篇文章之前&#xff0c;看一下往期文章&#xff09; &#xff08;1&#xff09;递归、搜索与回溯算法&#xff08;专题零&#xff1a;解释回溯算法中涉及到的名词&#xff09;【回溯算法入门必看】-CSDN博客 接下来我会用几道题&#…

Docker-安装实践(mysql,redis集群,tomcat)

docker实践(提供几个安装案例&#xff09; 安装Tomcat # 拉取镜像,可以指定标签不指定默认为最新 docker pull tomcat docker run -itd -p 8080:8080 --name tomcat tomcat:latest #这样内部默认80端口&#xff0c;主机的映射端口会随机分配一个 docker run -itd -P tomcat…

Python-基础篇-数据结构-列表、元组、字典、集合

文章目录 思维导图❓ 大抵是何物数据结构切片 &#x1f4ac;具体是何物列表&#x1f4bb; list&#x1f4bb; [ ]自我介绍精神面貌使用说明生理体征增删查改 方法汇总 元组&#x1f4bb; tuple&#x1f4bb; ( )自我介绍使用说明精神面貌生理体征增删查改 字典&#x1f4bb; di…

【C++】vector容器接口要点的补充

接口缩容 在VS编译器的模式下&#xff0c;类似于erase和insert接口的函数通常会进行缩容&#xff0c;因此&#xff0c;insert和erase行参中的迭代器可能会失效。下图中以erase为例&#xff1a; 代码如下&#xff1a; #include <iostream> #include <vector> #inclu…

Python——条形图正负不同色加表格

条形图&#xff0c;当差值大于0时设置一个颜色&#xff0c;反之另一种颜色&#xff0c;并添加表格 import pandas as pd import numpy as np import matplotlib.pyplot as plt import matplotlib.ticker as mtick import matplotlib.ticker as ticker#设置输出结果对齐方式 pd…