MongoDB 中如何使用 explain 分析查询计划

前言

创建完索引,如何分析索引的执行情况呢,MongoDB 中同样提供了 explain 来帮助我们进行分析,这里来看下 explain 的使用细节。

查询计划 explain

为了更好的了解 explain 的使用,这里首先来准备一个测试的表结构,并且预先插入数据,方便后面进行查询计划的分析。

for (var i = 1; i <1000000; i++) {
db.test_explain.insert({name:'user'+i,age:parseInt(Math.random()*100+1),sn:Math.floor(Math.random()*10000000)})
}

创建索引

db.test_explain.createIndex({age:-1},{background: true});

explain

explain 有三种模式,可以作为 explain 的参数进行模式选择

1、queryPlanner(默认模式);

2、executionStats;

3、allPlansExecution;

使用下面的查询条件来分析下

db.getCollection("test_explain").find({"age" : 59}).sort({_id: -1})
1、queryPlanner

queryPlanner 是 explain 默认的模式,queryPlanner 模式下不会真正的去执行 query 语句查询,查询优化器根据查询语句执行计划分析选出 winning plan

db.getCollection("test_explain").find({"age" : 59}).sort({_id: -1}).explain()

{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "gleeman.test_explain", // 查询的命名空间,作用于那个库的那个表
"indexFilterSet" : false, // 针对该query是否有 indexfilter,indexfilter 的作用见下文
"parsedQuery" : { // 解析查询条件,即过滤条件是什么,此处是 age = 59
"age" : {
"$eq" : 59
}
},
"winningPlan" : { //查询优化器根据该 query 选择的最优的查询计划
"stage" : "SORT", // 最优执行计划的,这里是 sort 表示在内存中具体的 stage 中的参数含义可见下文
"sortPattern" : {
"_id" : -1
},
"inputStage" : { // 用来描述子 stage,并且为其父 stage 提供文档和索引关键字,这里面含有着执行计划中比较主要的信息
"stage" : "SORT_KEY_GENERATOR", // 表示在内存中发生了排序
"inputStage" : {
"stage" : "FETCH", // FETCH 根据索引检索指定的文件
"inputStage" : {
"stage" : "IXSCAN", // stage 表示索引扫描
"keyPattern" : { // 查询命中的索引
"age" : -1
},
"indexName" : "age_-1", // 计算选择的索引的名字
"isMultiKey" : false, // 是否为多键索引,因为用到的索引是单列索引,这里是 false
"multiKeyPaths" : {
"age" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward", // 此 query 的查询状态,forward 是升序,降序则是 backward
"indexBounds" : { // 最优计划所扫描的索引范围
"age" : [
"[59.0, 59.0]" // [MinKey,MaxKey]
]
}
}
}
}
},
"rejectedPlans" : [ // 其他计划,因为不是最优而被查询优化器拒绝(reject)
{
"stage" : "FETCH",
"filter" : {
"age" : {
"$eq" : 59
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"_id" : 1
},
"indexName" : "_id_",
"isMultiKey" : false,
"multiKeyPaths" : {
"_id" : [ ]
},
"isUnique" : true,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "backward",
"indexBounds" : {
"_id" : [
"[MaxKey, MinKey]"
]
}
}
}
]
},
"serverInfo" : { // 服务器信息,包括主机名和ip,MongoDB的version等信息
"host" : "host-192-168-61-214",
"port" : 27017,
"version" : "4.0.3",
"gitVersion" : "0377a277ee6d90364318b2f8d581f59c1a7abcd4"
},
"ok" : 1,
"operationTime" : Timestamp(1693278617, 5),
"$clusterTime" : {
"clusterTime" : Timestamp(1693278617, 5),
"signature" : {
"hash" : BinData(0,"1fdWNqFjbdgCwBm3/NFEpD9yXjI="),
"keyId" : NumberLong("7233287468395528194")
}
}
}

上面的查询总结下来就是,age = 59 的查询使用到了 age 上面建立的索引,这块的匹配走的是 IXSCAN 也就是索引扫描。

查询中还有一个 sort 的排序,这个排序动作是在内存中进行的,对应到的 stage 就是 SORT。

因为 MongoDB 中内存排序对大数据量的排序效率不是很高,所以当有排序需求的时候,一般考虑创建组合索引,让排序在索引中完成。

2、executionStats

MongoDB 查询优化器会对当前的查询进行评估并且选择一个最佳的查询执行计划进行执行,在执行完毕后返回这个最佳执行计划执行完成时的相关统计信息,对于那些被拒绝的执行计划不返回器统计信息。

$ db.getCollection("test_explain").find({"age" : 59}).sort({_id: -1}).explain("executionStats");  

{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "gleeman.test_explain", // 查询的命名空间,作用于那个库那个表
"indexFilterSet" : false, // 针对该query是否有 indexfilter,indexfilter 的作用见下文
"parsedQuery" : { // 解析查询条件,即过滤条件是什么,此处是 age = 59
"age" : {
"$eq" : 59
}
},
"winningPlan" : { // 查询优化器针对该query所返回的最优执行计划的详细内容
"stage" : "SORT", // 最优执行计划的,这里是 sort 表示在内存中排序,具体的 stage 中的参数含义可见下文
"sortPattern" : {
"_id" : -1
},
"inputStage" : { // 用来描述子 stage,并且为其父 stage 提供文档和索引关键字,这里面含有着执行计划中比较主要的信息
"stage" : "SORT_KEY_GENERATOR", // 表示在内存中发生了排序
"inputStage" : {
"stage" : "FETCH", // FETCH 根据索引检索指定的文件
"inputStage" : {
"stage" : "IXSCAN", // 表示执行了索引扫描
"keyPattern" : { // 查询命中的索引
"age" : -1
},
"indexName" : "age_-1", // 查询选择的的索引的名字
"isMultiKey" : false, // 是否为多键索引,因为用到的索引是单列索引,这里是 false
"multiKeyPaths" : {
"age" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward", // 此 query 的查询状态,forward 是升序,降序则是 backward
"indexBounds" : { // 最优计划所扫描的索引范围
"age" : [
"[59.0, 59.0]"
]
}
}
}
}
},
"rejectedPlans" : [ // 其他计划,因为不是最优而被查询优化器拒绝(reject)
{
"stage" : "FETCH",
"filter" : {
"age" : {
"$eq" : 59
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"_id" : 1
},
"indexName" : "_id_",
"isMultiKey" : false,
"multiKeyPaths" : {
"_id" : [ ]
},
"isUnique" : true,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "backward",
"indexBounds" : {
"_id" : [
"[MaxKey, MinKey]"
]
}
}
}
]
},
"executionStats" : { // 已阶段树的形式纤细说明获胜执行计划的完成执行情况,例如,一个阶段可以有一个或者多个inputStage组成,每个阶段有特定于该阶段的执行信息组成。
"executionSuccess" : true, // 是否执行成功
"nReturned" : 4786, // 此 query 匹配到的文档数
"executionTimeMillis" : 26, // 查询计划选择和查询执行所需的总时间,单位:毫秒
"totalKeysExamined" : 4786, // 扫描的索引条目数
"totalDocsExamined" : 4786, // 扫描的文档数
"executionStages" : { // 最优计划完整的执行信息
"stage" : "SORT", // sort 表示在内存中发生了排序
"nReturned" : 4786,
"executionTimeMillisEstimate" : 20,
"works" : 9575, // 指定查询执行阶段执行的“工作单元”的数量。查询执行将其工作划分为小单元。
"advanced" : 4786, // 返回父阶段的结果数
"needTime" : 4788, // 将中间结果返回给其父级的工作循环数
"needYield" : 0, // 存储层请求查询系统产生锁定的次数
"saveState" : 113,
"restoreState" : 113,
"isEOF" : 1,
"invalidates" : 0,
"sortPattern" : {
"_id" : -1
},
"memUsage" : 362617,
"memLimit" : 33554432,
"inputStage" : { // 子执行单元,一个执行计划中,可以有一个或者多个inputStage
"stage" : "SORT_KEY_GENERATOR",
"nReturned" : 4786,
"executionTimeMillisEstimate" : 20,
"works" : 4788,
"advanced" : 4786,
"needTime" : 1,
"needYield" : 0,
"saveState" : 113,
"restoreState" : 113,
"isEOF" : 1,
"invalidates" : 0,
"inputStage" : {
"stage" : "FETCH",
"nReturned" : 4786,
"executionTimeMillisEstimate" : 10,
"works" : 4787,
"advanced" : 4786,
"needTime" : 0,
"needYield" : 0,
"saveState" : 113,
"restoreState" : 113,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 4786,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 4786,
"executionTimeMillisEstimate" : 10,
"works" : 4787,
"advanced" : 4786,
"needTime" : 0,
"needYield" : 0,
"saveState" : 113,
"restoreState" : 113,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"age" : -1
},
"indexName" : "age_-1",
"isMultiKey" : false,
"multiKeyPaths" : {
"age" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"age" : [
"[59.0, 59.0]"
]
},
"keysExamined" : 4786,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
}
}
},
"serverInfo" : {
"host" : "host-192-168-61-214",
"port" : 27017,
"version" : "4.0.3",
"gitVersion" : "0377a277ee6d90364318b2f8d581f59c1a7abcd4"
},
"ok" : 1,
"operationTime" : Timestamp(1694656526, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1694656526, 1),
"signature" : {
"hash" : BinData(0,"QaGoa0kgXBOfN9LA0px9V7NjU/c="),
"keyId" : NumberLong("7233287468395528194")
}
}
}
3、allPlansExecution

该模式包括上述2种模式的所有信息,即按照最佳的执行计划执行以及列出统计信息,如果存在其他候选计划,也会列出这些候选的执行计划。

下面的栗子就能看到,allPlansExecution 模式下,包含了上面两种查询模式的索引信息,这里不展开讨论了。

$ db.getCollection("test_explain").find({"age" : 59}).sort({_id: -1}).explain("allPlansExecution");  

{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "gleeman.test_explain",
"indexFilterSet" : false,
"parsedQuery" : {
"age" : {
"$eq" : 59
}
},
"winningPlan" : {
"stage" : "SORT",
"sortPattern" : {
"_id" : -1
},
"inputStage" : {
"stage" : "SORT_KEY_GENERATOR",
"inputStage" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"age" : -1
},
"indexName" : "age_-1",
"isMultiKey" : false,
"multiKeyPaths" : {
"age" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"age" : [
"[59.0, 59.0]"
]
}
}
}
}
},
"rejectedPlans" : [
{
"stage" : "FETCH",
"filter" : {
"age" : {
"$eq" : 59
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"_id" : 1
},
"indexName" : "_id_",
"isMultiKey" : false,
"multiKeyPaths" : {
"_id" : [ ]
},
"isUnique" : true,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "backward",
"indexBounds" : {
"_id" : [
"[MaxKey, MinKey]"
]
}
}
}
]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 4786,
"executionTimeMillis" : 78,
"totalKeysExamined" : 4786,
"totalDocsExamined" : 4786,
"executionStages" : {
"stage" : "SORT",
"nReturned" : 4786,
"executionTimeMillisEstimate" : 60,
"works" : 9575,
"advanced" : 4786,
"needTime" : 4788,
"needYield" : 0,
"saveState" : 113,
"restoreState" : 113,
"isEOF" : 1,
"invalidates" : 0,
"sortPattern" : {
"_id" : -1
},
"memUsage" : 362617,
"memLimit" : 33554432,
"inputStage" : {
"stage" : "SORT_KEY_GENERATOR",
"nReturned" : 4786,
"executionTimeMillisEstimate" : 50,
"works" : 4788,
"advanced" : 4786,
"needTime" : 1,
"needYield" : 0,
"saveState" : 113,
"restoreState" : 113,
"isEOF" : 1,
"invalidates" : 0,
"inputStage" : {
"stage" : "FETCH",
"nReturned" : 4786,
"executionTimeMillisEstimate" : 50,
"works" : 4787,
"advanced" : 4786,
"needTime" : 0,
"needYield" : 0,
"saveState" : 113,
"restoreState" : 113,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 4786,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 4786,
"executionTimeMillisEstimate" : 0,
"works" : 4787,
"advanced" : 4786,
"needTime" : 0,
"needYield" : 0,
"saveState" : 113,
"restoreState" : 113,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"age" : -1
},
"indexName" : "age_-1",
"isMultiKey" : false,
"multiKeyPaths" : {
"age" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"age" : [
"[59.0, 59.0]"
]
},
"keysExamined" : 4786,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
}
},
"allPlansExecution" : [
{
"nReturned" : 101,
"executionTimeMillisEstimate" : 60,
"totalKeysExamined" : 4786,
"totalDocsExamined" : 4786,
"executionStages" : {
"stage" : "SORT",
"nReturned" : 101,
"executionTimeMillisEstimate" : 60,
"works" : 4889,
"advanced" : 101,
"needTime" : 4788,
"needYield" : 0,
"saveState" : 76,
"restoreState" : 76,
"isEOF" : 0,
"invalidates" : 0,
"sortPattern" : {
"_id" : -1
},
"memUsage" : 362617,
"memLimit" : 33554432,
"inputStage" : {
"stage" : "SORT_KEY_GENERATOR",
"nReturned" : 4786,
"executionTimeMillisEstimate" : 50,
"works" : 4788,
"advanced" : 4786,
"needTime" : 1,
"needYield" : 0,
"saveState" : 76,
"restoreState" : 76,
"isEOF" : 1,
"invalidates" : 0,
"inputStage" : {
"stage" : "FETCH",
"nReturned" : 4786,
"executionTimeMillisEstimate" : 50,
"works" : 4787,
"advanced" : 4786,
"needTime" : 0,
"needYield" : 0,
"saveState" : 76,
"restoreState" : 76,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 4786,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 4786,
"executionTimeMillisEstimate" : 0,
"works" : 4787,
"advanced" : 4786,
"needTime" : 0,
"needYield" : 0,
"saveState" : 76,
"restoreState" : 76,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"age" : -1
},
"indexName" : "age_-1",
"isMultiKey" : false,
"multiKeyPaths" : {
"age" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"age" : [
"[59.0, 59.0]"
]
},
"keysExamined" : 4786,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
}
}
},
{
"nReturned" : 51,
"executionTimeMillisEstimate" : 10,
"totalKeysExamined" : 4889,
"totalDocsExamined" : 4889,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"age" : {
"$eq" : 59
}
},
"nReturned" : 51,
"executionTimeMillisEstimate" : 10,
"works" : 4889,
"advanced" : 51,
"needTime" : 4838,
"needYield" : 0,
"saveState" : 113,
"restoreState" : 113,
"isEOF" : 0,
"invalidates" : 0,
"docsExamined" : 4889,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 4889,
"executionTimeMillisEstimate" : 10,
"works" : 4889,
"advanced" : 4889,
"needTime" : 0,
"needYield" : 0,
"saveState" : 113,
"restoreState" : 113,
"isEOF" : 0,
"invalidates" : 0,
"keyPattern" : {
"_id" : 1
},
"indexName" : "_id_",
"isMultiKey" : false,
"multiKeyPaths" : {
"_id" : [ ]
},
"isUnique" : true,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "backward",
"indexBounds" : {
"_id" : [
"[MaxKey, MinKey]"
]
},
"keysExamined" : 4889,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
}
]
},
"serverInfo" : {
"host" : "host-192-168-61-214",
"port" : 27017,
"version" : "4.0.3",
"gitVersion" : "0377a277ee6d90364318b2f8d581f59c1a7abcd4"
},
"ok" : 1,
"operationTime" : Timestamp(1694999650, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1694999650, 1),
"signature" : {
"hash" : BinData(0,"Ew5W9lYNoAtbo9zyErAbjbrqMlw="),
"keyId" : NumberLong("7233287468395528194")
}
}
}

indexfilter

我们可以针对某些查询,指定特定的索引(索引必须存在)。如果查询条件吻合,就会使用指定的索引,如果指定了多个索引,会从中选出一个查询计划最优的索引执行。

db.runCommand(
{
planCacheSetFilter: <collection>, // 数据表
query: <query>, // 指定的查询条件
sort: <sort>, // 指定的排序条件
projection: <projection>,
indexes: [ <index1>, <index2>, ...] // 指定查询条件对应的索引
}
)

来个栗子

db.runCommand(
{
planCacheSetFilter: "orders",
query: { status: "A" },
indexes: [
{ status: 1,cust_id: 1, }
]
}
)

上面对 orders 表建立了一个 indexFilter,指定了查询条件,在查询 orders 表中的 status= A 时,就会命中 indexFilter 中指定的 indexes。

如果执行时通过 hint 指定了其他的 index,查询优化器将会忽略 hint 所设置 index,仍然使用 indexfilter 中设定的查询计划。

Stage 参数说明

来看下 Stage 中的参数

类型 描述
COLLSCAN 全表扫描
IXSCAN 索引扫描
FETCH 根据索引检索指定的文档
SHARD_MERGE 将各个分片的返回结果进行merge
SORT 表示在内存中进行了排序
LIMIT 使用 limit 限制返回结果的数量
SKIP 使用 SKIP 进行跳过
IDHACK 针对 _id 字段进行查询
SHANRDING_FILTER 通过 mongos 对分片数据进行查询
COUNT 利用 db.coll.explain().count() 进行 count 运算
COUNTSCAN count 不使用 index进行 count时的 stage 返回
COUNT_SCAN count 使用了 index进行 count时的 stage 返回
SUBPLA 未使用到索引的 $or 查询的 stage 返回
TEXT 使用全文索引进行查询时的 stage 返回
PROJECTION 限定返回字段时候stage的返回

总结

这里总结了 MongoDB 中使用 explain 来判断我们创建的索引计划是否合理。

其中常见的 explain 有三种模式,可以作为 explain 的参数进行模式选择

1、queryPlanner(默认模式);queryPlanner 是 explain 默认的模式,queryPlanner 模式下不会真正的去执行 query 语句查询,查询优化器根据查询语句执行计划分析选出 winning plan

2、executionStats;MongoDB 查询优化器会对当前的查询进行评估并且选择一个最佳的查询执行计划进行执行,在执行完毕后返回这个最佳执行计划执行完成时的相关统计信息,对于那些被拒绝的执行计划不返回器统计信息。

3、allPlansExecution;该模式包括上述2种模式的所有信息,即按照最佳的执行计划执行以及列出统计信息,如果存在其他候选计划,也会列出这些候选的执行计划。

一般使用默认模式就能满足我们的需求了

其中最核心的指标就是 Stage,通过这个参数,我们基本上就能判断我们创建的索引计划是否合理了。

参考

【MongoDB 中如何使用 explain 分析查询计划】https://boilingfrog.github.io/2023/09/18/mongodb中的explain/

【MongoDB简介】https://docs.mongoing.com/mongo-introduction

【MySQL 中的索引】https://www.cnblogs.com/ricklz/p/17262747.html

【performance-best-practices-indexing】https://www.mongodb.com/blog/post/performance-best-practices-indexing

【tune_page_size_and_comp】https://source.wiredtiger.com/3.0.0/tune_page_size_and_comp.html

【equality-sort-range-rule】https://www.mongodb.com/docs/manual/tutorial/equality-sort-range-rule/

【使用索引来排序查询结果】https://mongoing.com/docs/tutorial/sort-results-with-indexes.html

【Mongodb problem with sorting & indexes】https://groups.google.com/g/mongodb-user/c/YsY5h4KrwT4

【MongoDB - 执行计划 】https://www.cnblogs.com/Neeo/articles/14326471.html

MongoDB 中使用 explain 分析创建的索引是否合理的更多相关文章

  1. 「MySQL高级篇」explain分析SQL,索引失效&&常见优化场景

    大家好,我是melo,一名大三后台练习生 专栏回顾 索引的原理&&设计原则 欢迎关注本专栏:MySQL高级篇 本篇速览 在我们上一篇文章中,讲到了索引的原理&&设计原则 ...

  2. MongoDB实战指南(五):MongoDB中的聚集分析

    聚集操作是对数据进行分析的有效手段.MongoDB主要提供了三种对数据进行分析计算的方式:管道模式聚集分析,MapReduce聚集分析,简单函数和命令的聚集分析. 1. 管道模式进行聚集 这里所说的管 ...

  3. MongoDB中的explain和hint提的使用

    一.简介 这里简单介绍一下各个工具的使用场景,一般用mysql,redis,mongodb做存储层,hadoop,spark做大数据分析. mysql适合结构化数据,类似excel表格一样定义严格的数 ...

  4. 聊聊MongoDB中连接池、索引、事务

    大家好,我是哪吒. 三分钟你将学会: MongoDB连接池的使用方式与常用参数 查询五步走,能活九十九? MongoDB索引与MySQL索引有何异同? MongoDB事务与ACID 什么是聚合框架? ...

  5. 【实战】使用 Kettle 工具将 mysql 数据增量导入到 MongoDB 中

    最近有一个将 mysql 数据导入到 MongoDB 中的需求,打算使用 Kettle 工具实现.本文章记录了数据导入从0到1的过程,最终实现了每秒钟快速导入约 1200 条数据.一起来看吧~ 一.K ...

  6. MongoDB 索引 explain 分析查询速度

    一.索引基础索引是对数据库表中一列或多列的值进行排序的一种结构,可以让我们查询数据库变得更快.MongoDB 的索引几乎与传统的关系型数据库一模一样,这其中也包括一些基本的查询优化技巧.下面是创建索引 ...

  7. 在MongoDB中执行查询、创建索引

    1. MongoDB中数据查询的方法 (1)find函数的使用: (2)条件操作符: (3)distinct找出给定键所有不同的值: (4)group分组: (5)游标: (6)存储过程. 文档查找 ...

  8. 在MongoDB中执行查询与创建索引

    实验目的: (1)掌握MongoDB中数据查询的方法: (2)掌握MongoDB中索引及其创建: 实验内容: 一. MongoDB中数据查询的方法: (1)find函数的使用: (2)条件操作符: a ...

  9. MongoDB 创建基础索引、组合索引、唯一索引以及优化

    一.索引 MongoDB 提供了多样性的索引支持,索引信息被保存在system.indexes 中,且默认总是为_id创建索引,它的索引使用基本和MySQL 等关系型数据库一样.其实可以这样说说,索引 ...

  10. mongodb中的排序和索引快速学习

    在mongodb中,排序和索引其实都是十分容易的,先来小结下排序: 1 先插入些数据    db.SortTest.insert( { name : "Denis", age : ...

随机推荐

  1. Linux常用磁盘管理命令详解

    du du命令用于查看文件和目录磁盘的使用空间. 命令语法:du [参数] [文件或目录名称] 参数说明: 参数 说明 -a 列出所有的文件与目录容量. -h 以G.M.K为单位,返回容量. -s 列 ...

  2. C++面试八股文:在C++中,有哪些可执行体?

    某日二师兄参加XXX科技公司的C++工程师开发岗位第14面: 面试官:在C++中,有哪些可执行体? 二师兄:可执行体? 面试官:也就是可调用对象. 二师兄:让我想一想.函数.函数指针.类的静态方法.类 ...

  3. CMake个人理解和使用

    前言 CMake是一个构建工具,通过它可以很容易创建跨平台的项目.通常使用它构建项目要分两步,通过源代码生成工程文件,通过工程文件构建目标产物(可能是动态库,静态库,也可能是可执行程序).使用CMak ...

  4. 归并排序Java版(图文并茂思路分析)

    归并排序 工作原理: 工作原理是将一个大问题分解成小问题,再将小问题分解成更小的.(乍一看就觉得是像一个递归)就像下图这样.然后不断的将其一份为二,分解成更小的排序. 我们设一个函数叫MergeSor ...

  5. Java判断一个数是不是质数

    判断一个数是不是质数 做这个题之前我们需要先进行了解什么是质数 质数:只能被1和它本身整除的数 举一个简单的例子:数字5是不是质数呢? 我们可以进行分析: 解题思路:5可以分为1 2 3 4 5,我们 ...

  6. ABP - 本地事件总线

    1. 事件总线 在我们的一个应用中,经常会出现一个逻辑执行之后要跟随执行另一个逻辑的情况,例如一个用户创建了后续还需要发送邮件进行通知,或者需要初始化相应的权限等.面对这样的情况,我们当然可以顺序进行 ...

  7. 每日一题力扣 1262 https://leetcode.cn/problems/greatest-sum-divisible-by-three/

    . 题解 这道题目核心就算是要知道如果x%3=2的话,应该要去拿%3=1的数字,这样子才能满足%3=0 贪心 sum不够%3的时候,就减去余数为1的或者余数为2的 需要注意 两个余数为1会变成余数为2 ...

  8. 【从0开始编写webserver·基础篇#03】TinyWeb源码阅读,还是得看看靠谱的项目

    [前言] 之前通过看书.看视频和博客拼凑了一个webserver,然后有一段时间没有继续整这个项目 现在在去看之前的代码,真的是相当之简陋,而且代码设计得很混乱,我认为没有必要继续在屎堆上修改了,于是 ...

  9. kubernetes(k8s):解决不在同一网段加入集群失败问题

    执行下面命令,将内外网进行映射. iptables -t nat -A OUTPUT -d 10.140.128.121 -j DNAT --to-destination 10.170.129.153 ...

  10. 攻防世界web高手进阶区-ics-06

    今天借着这道web题顺便学会了利用burpsuite进行爆破 先摆题目 打开题目环境,发现是一个工程管理系统,根据题目找到报表中心,点进去 好像没什么收获,F12看一下,发现id =1,试了一下id= ...