Mongodb索引

avatar
作者
筋斗云
阅读量:0

MongoDB中的索引(Indexes)是为了加速查询而创建的数据结构。MongoDB的索引与关系数据库的索引类似,可以显著提高读取操作的性能。

mongodb中的索引概念

  • 默认索引:MongoDB在每个集合上都会自动创建一个包含_id字段的唯一索引。
  • 自定义索引:可以根据查询需要在单个或多个字段上创建索引。

索引类型

单字段索引:在单个字段上创建索引。

db.collection.createIndex({ field: 1 })  // 1表示升序 

复合索引:在多个字段上创建索引,字段的顺序很重要。

db.collection.createIndex({ field1: 1, field2: -1 })  // field1升序,field2降序 

多键索引(Multikey Index):用于数组字段的索引,每个数组元素都被索引。

db.collection.createIndex({ arrayField: 1 }) 

文本索引(Text Index):用于文本搜索,支持对字符串内容的全文搜索。

db.collection.createIndex({ field: "text" })

哈希索引(Hashed Index):对字段值进行哈希计算,用于分片键。

db.collection.createIndex({ field: "hashed" })

地理空间索引(Geospatial Index):用于地理位置数据,支持2d和2dsphere索引。

db.collection.createIndex({ location: "2dsphere" })  // 对GeoJSON数据使用 

唯一索引(Unique Index):确保索引字段的值唯一。

db.collection.createIndex({ field: 1 }, { unique: true })

部分索引(Partial Index):只索引集合中符合指定条件的文档。

db.collection.createIndex({ field: 1 }, { partialFilterExpression: { status: "active" } })

稀疏索引(Sparse Index):只索引那些包含索引字段的文档。

db.collection.createIndex({ field: 1 }, { sparse: true }) 

TTL索引(Time-to-Live):自动删除过期的文档,只能用于日期字段。

db.collection.createIndex(    { "field": 1 },    { expireAfterSeconds: <seconds> } )   # 30天后过期 db.logs.createIndex(    { "create_time": 1 },    { expireAfterSeconds: 30 * 24 * 60 * 60 }  // 30天的秒数 ) 

索引操作

查看索引

db.collection.getIndexes() 

删除索引

db.collection.dropIndex("index_name") 

删除所有索引

db.collection.dropIndexes() 

索引优化器

  • 查询优化器(Query Optimizer):MongoDB查询优化器会根据查询条件选择最优的索引。
  • Explain Plan:可以使用explain()方法查看查询的执行计划和使用的索引。
    db.collection.find({ field: value }).explain("executionStats") 

    查询结果和结果说明

    {     "explainVersion": "1",                    	    // 显示explain命令的版本     "queryPlanner": {							    // 包含关于查询计划的信息         "namespace": "mydb.test1",				    // 查询的数据库和集合         "indexFilterSet": false,				    // 表示是否有索引过滤器应用, false 表示没有应用索引过滤器         "parsedQuery": {						    // 表示解析后的查询条件             "name": {                 "$eq": "name_99999"             }         },         "queryHash": "A2F868FD",					// 查询的哈希值,用于查询计划缓存         "planCacheKey": "A3E454E0",					// 查询计划缓存的键         "maxIndexedOrSolutionsReached": false,		// 是否达到了最大的OR解决方案数量, false 表示未达上限         "maxIndexedAndSolutionsReached": false,		// 是否达到了最大的AND解决方案数量, false 表示未达上限         "maxScansToExplodeReached": false,			// 是否达到了扫描的最大数量, false 表示未达上限         "winningPlan": {							// 表示被选中的查询执行计划             "stage": "FETCH",						// 当前执行计划的阶段, "FETCH" 表示当前阶段是从索引中获取文档             "inputStage": {							// 表示输入阶段的计划,通常是索引扫描                 "stage": "IXSCAN",					// 当前阶段的操作, "IXSCAN" 表示索引扫描                 "keyPattern": {						// 索引的键模式                     "name": 1						// 表示在name字段上创建了升序索引                 },                 "indexName": "name_1",				// 索引的名称                 "isMultiKey": false,				// 是否为多键索引, false 表示不是多键索引                 "multiKeyPaths": {					// 多键索引的路径                     "name": [ ]						// { "name": [ ] } 表示name字段不是多键索引                 },                 "isUnique": false,					// 索引是否唯一, false 表示索引不是唯一的                 "isSparse": false,					// 索引是否稀疏, false 表示索引不是稀疏的                 "isPartial": false,					// 索引是否部分索引, false 表示索引不是部分索引                 "indexVersion": NumberInt("2"),		// 索引版本, 2 表示索引的版本号                 "direction": "forward",				// 索引扫描的方向, "forward" 表示升序扫描                 "indexBounds": {					// 索引范围                     "name": [                         "[\"name_99999\", \"name_99999\"]"		// 表示查询范围为"name_99999"到"name_99999"                     ]                 }             }         },         "rejectedPlans": [ ]						// 被拒绝的计划列表, [] 表示没有被拒绝的计划     },     "executionStats": {								// 包含关于查询执行的统计信息         "executionSuccess": true,					//****** 查询是否成功执行, true 表示成功         "nReturned": NumberInt("1"),				//****** 返回的文档数量         "executionTimeMillis": NumberInt("0"),		//****** 查询执行使用了多长时间(毫秒)         "totalKeysExamined": NumberInt("1"),		// 扫描的索引键总数, 1 表示扫描了1个索引键         "totalDocsExamined": NumberInt("1"),		//****** 扫描的文档总数, 1 表示扫描了1个文档         "executionStages": {						// 执行阶段的详细统计信息             "stage": "FETCH",						// 执行阶段, "FETCH" 表示从索引中提取文档             "nReturned": NumberInt("1"),			// 从此阶段返回的文档数量, 1 表示返回了1个文档             "executionTimeMillisEstimate": NumberInt("0"),	// 执行时间的估算值(毫秒)             "works": NumberInt("2"),				// 当前阶段的工作次数, 2 表示工作了2次             "advanced": NumberInt("1"),				// 当前阶段的“高级”次数, 1 表示有1次“高级”操作             "needTime": NumberInt("0"),				// 当前阶段的“需要时间”次数, 0 表示没有“需要时间”操作             "needYield": NumberInt("0"),			// 当前阶段的“需要让步”次数, 0 表示没有“需要让步”操作             "saveState": NumberInt("0"),			// 当前阶段的“保存状态”次数, 0 表示没有“保存状态”操作             "restoreState": NumberInt("0"),			// 当前阶段的“恢复状态”次数, 0 表示没有“恢复状态”操作             "isEOF": NumberInt("1"),				// 是否到达文件末尾, 1 表示到达文件末尾             "docsExamined": NumberInt("1"),			// 在此阶段检查的文档数量, 1 表示检查了1个文档             "alreadyHasObj": NumberInt("0"),		// 已经拥有对象的次数, 0 表示没有“已经拥有对象”的操作             "inputStage": {							// 输入阶段的详细统计信息(通常是IXSCAN)                 "stage": "IXSCAN",					// 输入阶段的操作, "IXSCAN" 表示索引扫描                 "nReturned": NumberInt("1"),		// 从此阶段返回的文档数量, 1 表示返回了1个文档                 "executionTimeMillisEstimate": NumberInt("0"),	// 执行时间的估算值(毫秒)                 "works": NumberInt("2"),			// 输入阶段的工作次数, 2 表示工作了2次                 "advanced": NumberInt("1"),			// 输入阶段的“高级”次数, 1 表示有1次“高级”操作                 "needTime": NumberInt("0"),			// 输入阶段的“需要时间”次数, 0 表示没有“需要时间”操作                 "needYield": NumberInt("0"),		// 输入阶段的“需要让步”次数, 0 表示没有“需要让步”操作                 "saveState": NumberInt("0"),		// 输入阶段的“保存状态”次数, 0 表示没有“保存状态”操作                 "restoreState": NumberInt("0"),		// 输入阶段的“恢复状态”次数, 0 表示没有“恢复状态”操作                 "isEOF": NumberInt("1"),			// 是否到达文件末尾, 1 表示到达文件末尾                 "keyPattern": {						// 索引的键模式                     "name": 1						// 表示在name字段上创建了升序索引                 },                 "indexName": "name_1",				// 索引的名称                 "isMultiKey": false,				// 是否为多键索引, false 表示不是多键索引                 "multiKeyPaths": {					// 多键索引的路径                     "name": [ ]                 },                 "isUnique": false,					// 索引是否唯一, false 表示索引不是唯一的                 "isSparse": false,					// 索引是否稀疏, false 表示索引不是稀疏的                 "isPartial": false,					// 索引是否部分索引, false 表示索引不是部分索引                 "indexVersion": NumberInt("2"),		// 索引版本, 2 表示索引的版本号                 "direction": "forward",				// 索引扫描的方向, "forward" 表示升序扫描                 "indexBounds": {					// 索引范围                     "name": [                         "[\"name_99999\", \"name_99999\"]"                     ]                 },                 "keysExamined": NumberInt("1"),		// 扫描的索引键数量, 1 表示扫描了1个索引键                 "seeks": NumberInt("1"),			// 索引扫描的次数, 1 表示进行了1次索引扫描                 "dupsTested": NumberInt("0"),		// 测试的重复记录数, 0 表示没有测试重复记录                 "dupsDropped": NumberInt("0")		// 丢弃的重复记录数, 0 表示没有丢弃重复记录             }         }     },     "command": {									// 表示执行的实际命令         "find": "test1",							// 查询的集合         "filter": {									// 查询条件             "name": "name_99999"         },         "$db": "mydb"								// 数据库名称     },     "serverInfo": {									// 提供关于MongoDB服务器的信息         "host": "71.xx",							// 服务器的主机名         "port": NumberInt("27017"),					// 服务器的端口         "version": "7.0.12",						// MongoDB的版本         "gitVersion": "b6513ce0781db6818e24619e8a461eae90bc94fc"		// MongoDB的Git版本     },     "serverParameters": {							// 显示MongoDB服务器的内部参数, 这些参数通常用于调试和性能调优         "internalQueryFacetBufferSizeBytes": NumberInt("104857600"),         "internalQueryFacetMaxOutputDocSizeBytes": NumberInt("104857600"),         "internalLookupStageIntermediateDocumentMaxSizeBytes": NumberInt("104857600"),         "internalDocumentSourceGroupMaxMemoryBytes": NumberInt("104857600"),         "internalQueryMaxBlockingSortMemoryUsageBytes": NumberInt("104857600"),         "internalQueryProhibitBlockingMergeOnMongoS": NumberInt("0"),         "internalQueryMaxAddToSetBytes": NumberInt("104857600"),         "internalDocumentSourceSetWindowFieldsMaxMemoryBytes": NumberInt("104857600"),         "internalQueryFrameworkControl": "trySbeRestricted"     },     "ok": 1											//****** 表示命令是否成功执行, 1 表示成功 } 

    stage的选项

1. COLLSCAN(Collection Scan)

  • 说明: 执行全表扫描,逐一检查每个文档,以满足查询条件。
  • 适用场景: 当没有合适的索引时,MongoDB会执行全表扫描。

2. IXSCAN(Index Scan)

  • 说明: 执行索引扫描,使用索引来查找匹配的文档。
  • 适用场景: 当查询可以利用索引加速时,MongoDB会使用索引扫描。

3. FETCH(Fetch)

  • 说明: 从索引中获取文档,并检索实际的文档数据。
  • 适用场景: 通常在IXSCAN之后执行,以从索引中提取实际文档。

4. SORT(Sort)

  • 说明: 对文档进行排序。
  • 适用场景: 当查询结果需要排序时使用。

5. LIMIT(Limit)

  • 说明: 限制返回的文档数量。
  • 适用场景: 当查询包含limit操作符时使用。

6. PROJECT(Project)

  • 说明: 选择返回的字段。
  • 适用场景: 当查询使用projection操作符来指定返回的字段时使用。

7. REDUCE(Reduce)

  • 说明: 对查询结果进行汇总或合并。
  • 适用场景: 通常在某些复杂的聚合操作中出现。

8. MERGE(Merge)

  • 说明: 将多个结果合并为一个结果集。
  • 适用场景: 通常在复合查询或聚合管道中出现。

9. UNWIND(Unwind)

  • 说明: 将数组字段展开为多个文档。
  • 适用场景: 在处理数组字段时使用,特别是在$unwind阶段的聚合管道中。

10. GROUP(Group)

  • 说明: 将文档分组并计算汇总值。
  • 适用场景: 在聚合管道中的$group阶段出现。

11. LOOKUP(Lookup)

  • 说明: 执行集合间的联合操作。
  • 适用场景: 在聚合管道中的$lookup阶段出现。

12. OUT(Out)

  • 说明: 将聚合结果输出到另一个集合。
  • 适用场景: 在聚合管道中的$out阶段出现。

13. INDEXONLY(Index Only)

  • 说明: 查询只使用索引,不需要访问实际的文档。
  • 适用场景: 当查询只需要索引中的字段时使用。

14. SHARD(Shard)

  • 说明: 执行跨分片的查询操作。
  • 适用场景: 在分片集群中,当查询需要跨多个分片时使用。

15. REPARTITION(Repartition)

  • 说明: 对数据进行重新分区。
  • 适用场景: 在某些复杂的聚合管道中可能会出现。

16. PLATFORM(Platform)

  • 说明: 表示使用了某种平台或引擎的特殊执行阶段。
  • 适用场景: 与MongoDB的特定引擎或平台相关的操作。

索引的局限性

  • 写操作开销:索引会增加写操作的开销,因为每次写操作都需要更新索引。
  • 存储空间:索引会占用额外的存储空间,特别是多键索引可能会大幅增加存储需求。

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!