Code前端首页关于Code前端联系我们

MongoDB 快速入门指南:MongoDB 索引

terry 2年前 (2023-09-26) 阅读数 47 #数据库

4.1 概述

索引支持在 MongoDB 中高效执行搜索。如果没有索引,MongoDB 必须执行完整的集合扫描,即扫描集合中的每个文档以选择文档匹配语句查询。扫描整个集合的查询效率很低。尤其是在处理大量数据时,搜索可能需要几十秒甚至几分钟,这对于网站的性能来说是非常致命的。

如果存在适合搜索的索引,MongoDB可以使用该索引来限制要检查的文档数量。

索引是一种特殊的数据结构,它以易于遍历的形式存储数据集合的一小部分。索引存储按字段值排序的特定字段或字段值组。排序索引条目支持高效的等式匹配和基于范围的查询操作。此外,MongoDB还可以在索引中使用排序来返回排序结果。

MongoDB的使用方式与MySQL相同。是B+树吗

以前的版本Mongo用的是B树,现在用的是B+树

  • Mongo官方文档
  • Mongo为什么选择B树? TM 单字段索引 (单字段索引)

    对于单字段索引和排序操作,索引键的排序顺序(即升序或降序)并不重要,因为 MongoDB 可以按任意顺序移动索引

    MongoDB快速上手指南:MongoDB 的索引

    4.2.2 复合索引

    MongoDB还支持用户自定义多个字段的索引,即复合索引。这其实和MySQL中的联合索引非常相似,由于底层是B+树,所以所有联合索引也可以有最左原则类似

    之类的东西。复合索引中显示的字段顺序是有意义的。例如,如果复合索引由 { userid: 1, Score: -1 } 组成,则该索引首先按 userid 按正序排序,然后在以下值内排序每个userid,然后按照分数排序。

    MongoDB快速上手指南:MongoDB 的索引

    4.2.3其他索引

    • 地理空间索引
    • 文本索引
    • 哈希索引 哈希索引
    地理空间索引为

    为了支持地理空间坐标数据的高效检索,MongoDB提供了两种特殊索引:返回结果时使用平面几何的二维索引和返回结果时使用球面几何的二维球形索引。

    文本索引(Text Indexes)

    MongoDB提供了一种文本索引,支持在集合中搜索字符串内容。这些文本索引不存储特定于语言的停用词(例如“the”、“a”、“of”),而是使用集合中的单词作为词干并仅存储词根。

    哈希索引

    为了支持基于哈希的分片,MongoDB 提供了哈希索引类型,该类型对字段值进行哈希处理。列已建立索引。这些索引在其范围内的值分布更加随机,但仅支持相等匹配,不支持基于范围的查询。

    4.3 索引管理操作

    4.3.1 查看索引

    语法

    db.collection.getIndexes()
    复制代码

    提示:该语法命令需要 MongoDB 3.0+

    【示例】查看评论集合中所有索引

    MongoDB快速上手指南:MongoDB 的索引

    默认_id -index显示在结果中I 默认_ID默索引:创建集合时,MongoDB在字段_id中创建了唯一索引,默认名称为_id,即索引的索引。索引 为了防止客户端插入两个具有相同值的文档,不能删除 _id 字段中的索引。

    注意:该索引是唯一的索引,因此值不能重复。即_id值不能重复。

    在分片集群中,_id通常用作分片键.

    4。 3.2 索引创建

    语法

    db.collection.createIndex(keys, options)
    复制代码

    参数

    MongoDB快速上手指南:MongoDB 的索引

    选项列表(更多选项)

    MongoDB快速上手指南:MongoDB 的索引

    注意3.0.0版本之前的索引创建方法db.collection.ensureIndex()是,而以后的版本使用方法 db.collection.createIndex()ensureIndex()仍然可以使用,但它只是createIndex()的别名.

    举个例子?

    userid:1表示按userid升序创建索引,userid:1,昵称:-1} 意味着首先按用户 ID 升序,如果用户 ID 相等,则按用户名降序。创建索引,与 MySQL 完全一样

    // 先由userid按照升序创建索引
    $  db.comment.createIndex({userid:1})
    {
      "createdCollectionAutomatically" : false,
      "numIndexesBefore" : 1,
      "numIndexesAfter" : 2,
      "ok" : 1
    }
    // 先按userid升序,如果userid相等再按照nickname降序创建索引
    $ db.comment.createIndex({userid:1,nickname:-1})
    ...
    复制代码

    MongoDB快速上手指南:MongoDB 的索引

    MongoDB快速上手指南:MongoDB 的索引

    4.3.3 索引删除

    语法

    # 删除某一个索引
    $ db.collection.dropIndex(index)
    
    # 删除全部索引
    $ db.collection.dropIndexes()
    复制代码

    其中是 index 类型:字符串或文档,表示索引应该是删除就放弃了。索引可以通过索引名称或索引规范文档来指定。要删除文本索引,请指定索引名称。

    温馨提示:

    _id字段的索引不可删除,只能删除_id以外的字段索引

    示例

    # 删除 comment 集合中 userid 字段上的升序索引
    $ db.comment.dropIndex({userid:1})
    复制代码

    MongoDB快速上手指南:MongoDB 的索引

    4.4索引使用

    4.4。 1 执行计划

    分析查询性能(Analyze Query Performance) 通常使用执行计划(Explain Plan)来查看查询情况

    $ db.<collection_name>.find( query, options ).explain(options)
    复制代码

    例如:根据user_id查看查询数据情况索引

    “stage”前添加:“COLLSCAN”,表示全收集扫描

    MongoDB快速上手指南:MongoDB 的索引

    添加索引后

    “stage”:“IXSCAN”,基于索引scan

    MongoDB快速上手指南:MongoDB 的索引

    4.4 .2 覆盖查询(Covered Queries)

    直接看的话其实挺难理解的,但是如果我们结合MySQL来看,你就会发现这不是 MySQL 中的覆盖索引吗?不覆盖索引会导致表返回减少吗?既然如此,下面的介绍你一下子就能明白。看来知识都是有联系的。底层还是应该多了解一下。应用层的东西会改变,但底层的大部分东西不会改变。你看AVL树、红黑树这些数据结构都是上世纪中叶产生的,今天还在使用这套

    当查询条件和查询投影仅包含索引字段。MongoDB直接从索引返回结果,无需扫描文档或记忆文档。这些覆盖的查询非常高效

    MongoDB快速上手指南:MongoDB 的索引

    docs.mongodb.com/manual/core…

    例如我们请求如下索引执行计划:

    MongoDB快速上手指南:MongoDB 的索引

    作者:小亮
    链接:https://juejin .cn/post /7126746699527094303
    来源:稀土掘金
    版权归作者所有。商业转载请联系作者获得许可。非商业转载请注明出处。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门