MongoDB之索引

这篇具有很好参考价值的文章主要介绍了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树,通过索引能更快访问,但不适合范围查询。
MongoDB之索引,海量数据存储专栏,mongodb,数据库
B树特点

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

跟B+树的区别:文章来源地址https://www.toymoban.com/news/detail-809652.html

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

到了这里,关于MongoDB之索引的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据库MongoDB】MongoDB与大数据关系以及MongoDB中重要的进程:mongod进程与mongo进程关系

    云计算的定义有多种说法,对于到底什么是云计算,我们至少可以找到100种解释。目前广为接受的是美国国家标准与技术研究院定义: 云计算是一种按使用量付费的模式,这种模式提供可用的、便捷的、按需的网络访问,进入可配置的计算资源共享池(资源包括网络、服务器

    2024年02月02日
    浏览(68)
  • 〖Python 数据库开发实战 - MongoDB篇⑧〗- MongoDB的数据结构

    订阅 Python全栈白宝书-零基础入门篇 可报销! 白嫖入口-请点击我。 推荐他人订阅,可获取扣除平台费用后的35%收益,文末名片加V! 说明:该文属于 Python全栈白宝书专栏, 免费阶段订阅数量4300+ , 购买任意白宝书体系化专栏可加入 TFS-CLUB 私域社区。 福利:加入社区的小伙

    2023年04月09日
    浏览(79)
  • MongoDB——MongoDB删除系统自带的local数据库

    1.1、linux环境进入mongo客户端 输入 mongo 命令,进入命令行客户端 进入admin库,并登录,查看所有数据库 提升用户权限,然后进入local库并删除local库 然后重新进入admin库,把提升的用户权限降回,再次查看所有数据库 由上图可知,local库已被删除。

    2024年02月06日
    浏览(54)
  • [虚幻引擎 MongoDB Client 插件说明] DTMongoDB MongoDB数据库连接插件,UE蓝图可以操作MongoDB数据库增删改查。

    本插件可以在UE里面使用蓝图操作MongoDB数据库, 对数据库进行查询,删除,插入,替换,更新操作。 插件下载地址在文章最后。 Create MongoDB Client - 创建客户端对象 创建一个 MongoDB 客户端对象。 Connect By Url - 连接到数据库 Url :MongoDB的连接地址。 如 mongoDB://account:password@ip:

    2024年02月14日
    浏览(91)
  • mysql 海量数据设计:对数据库存储有深入研究

    索引: 聚簇索引 二级索引 联合索引:最左匹配原则、自动优化顺序 索引优化方向: 存储空间 主键选择:自增主键、随机主键、业务主键 如何设计一个雪花算法: 正数 + 时间戳 + 机器id(固定) + 服务id + 序号 雪花算法优点: 高并发分布式环境下生成不重复 id,每秒可生成百

    2023年04月24日
    浏览(39)
  • 基于MongoDB的空间数据存储与查询

    MongoDB 中使用 GeoJSON对象 或 坐标对 描述空间地理数据。MongoDB使用 WGS84 参考系进行地理空间数据查询。 1、MongoDB支持空间数据的存储,数据类型需要限制为GeoJSON; 2、MongoDB可以为GeoJSON类型数据建立索引,提升空间查询的效率; GeoJSON 对象格式 GeoJSON 对象有两个filed,分别是 ty

    2024年02月11日
    浏览(25)
  • MongoDB数据库从入门到精通系列文章之:MongoDB数据库百篇技术文章汇总

    MongoDB数据库系列文章持续更新中: 更多数据库内容请阅读博主数据库专栏,数据库专栏涵盖了Mysql、SQLServer、PostgreSQL、MongoDB、Oracle、Cassandra等数据库 数据库专栏 文章名称 文章链接 数据库安装部署系列之:部署Mongodb5.0.6高可用集群详细步骤 数据库安装部署系列之:部署M

    2024年02月11日
    浏览(54)
  • Mongodb连接数据库

    npm init   npm i mongoose  const mongoose=require(\\\"mongoose\\\") mongoose.connect(\\\"mongodb://127.0.0.1:27017/user\\\") 说明:mongodb是协议,user是数据库,如果没有会自动创建user数据库 。 node 文件名     mongoose.disconnect()

    2024年02月15日
    浏览(59)
  • mongodb数据库操作

    1、启动mongodb 在mongodb启动命令中 --dbpath 指定mongodb的数据存储路径 --logpath 指定mongodb的日志存储路径 2、停止mongodb 第一步先进入mongo命令行模式 第二步,使用use admin 命令进入admin数据库 第三步,执行 db.shutdownServer()命令 停止服务。代码及显示如下:  2 、导出Mongodb数据 mon

    2024年02月09日
    浏览(50)
  • MongoDb数据库

    1.显示所有数据库: show dbs 2.切换到指定数据库,如果没有则自动创建数据库 use databaseName 3.显示当前所在数据库 db 4.删除当前数据库 use 库名 db.dropDatabase() 1.创建集合 db.createCollection(\\\'集合名称\\\') 2.显示当前数据库中所有集合 show colletions  3.删除某个集合 db.xxx.drop(); 4.重命名集

    2024年02月04日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包