MongoDB索引的创建和删除(附带实例)
MongoDB 数据库索引支持高效执行查询。如果没有索引,MongoDB 就必须扫描集合中的每个文档以返回查询结果。如果数据库存在适当的索引,MongoDB 就可以使用该索引来限制查询必须扫描的文档数。
MongoDB 索引可提高查询性能,但添加索引会影响写入操作的性能。对于写入读取率高的集合,由于每次插入操作都必须同时更新所有索引,因此会带来较高的索引成本。如果应用程序对相同字段重复运行查询,则可以为这些字段创建索引以提高性能。
MongoDB 索引是一种特殊的数据结构,以易于遍历的形式存储小部分集合数据集。MongoDB 索引使用 B-tree 数据结构,索引可以存储某个特定字段或多个字段的值,并按字段的值进行排序。索引条目的排序支持高效的相等匹配和基于范围的查询操作。此外,MongoDB 还可以使用索引中的顺序来返回排序后的结果。
MongoDB 索引包括默认索引(Default Index)、索引名称和索引构建性能三方面的内容,具体介绍如下:
如果要在 MongoDB 数据库中创建索引,可以使用 Shell 中的 createIndex() 方法或适用于驱动程序的等效方法。在 MongoDB Shell 或驱动程序中运行创建索引的命令时,MongoDB 仅在没有相同规格索引存在时才会成功创建索引。
同时,尽管在 MongoDB 数据库中创建索引可以提高查询性能,但添加索引会对写入操作的性能产生负面影响。对于具有高写入读取比率的集合,索引的成本很高,因为每次插入和更新还必须更新所有索引。
如果要使用 Node.js 驱动程序创建索引,可以使用 createIndex() 方法:
下面的代码会在 name 字段上创建一个单键降序索引:
若要确认索引已创建,可以使用 mongosh 运行 db.collection.getIndexes() 方法:
例如,如果索引具有不同名称,则可以更轻松地在查询计划的解释结果中识别查询使用的索引。想要指定索引名称,可以在创建索引时包含 name 选项,具体代码如下:
在指定索引名称之前,需考虑以下几点:
在下面的应用示例中,博客(Blog)集合包含有关博文与用户交互的数据,在 content、users.comments 和 users.profiles 字段上创建文本索引,同时将索引 name 设置为 InteractionsTextIndex。具体代码如下:
在创建索引后,可以使用 db.collection.getIndexes() 方法获取索引名称。具体代码如下:
想要删除索引,可以使用下表所示的 Shell 方法:
设计人员可以删除 _id 字段上的默认索引之外的任何索引,如果要删除 _id 索引,则必须删除整个集合。删除生产环境中频繁使用的索引可能会导致性能下降。在删除索引之前,需要考虑隐藏索引以评估删除索引的潜在影响。
如果要删除索引,则需要知道它的名称。想要获取集合的所有索引名称,可以运行 getIndexes() 方法,具体代码如下:
在确定要删除的索引后,需要对指定的集合使用下列一种删除方法,具体说明如下:
1) 删除单个索引。要删除特定索引,可使用 dropIndex() 方法并指定索引名称:
2) 删除多个索引。要删除多个索引,可使用 dropIndexes() 方法并指定索引名称数组:
3) 删除 _id 索引之外的所有索引。要删除 _id 索引之外的所有索引,可使用 dropIndexes() 方法:
想要确认索引已删除,可以运行 db.collection.getIndexes() 方法,具体代码如下:
MongoDB 索引可提高查询性能,但添加索引会影响写入操作的性能。对于写入读取率高的集合,由于每次插入操作都必须同时更新所有索引,因此会带来较高的索引成本。如果应用程序对相同字段重复运行查询,则可以为这些字段创建索引以提高性能。
MongoDB 索引是一种特殊的数据结构,以易于遍历的形式存储小部分集合数据集。MongoDB 索引使用 B-tree 数据结构,索引可以存储某个特定字段或多个字段的值,并按字段的值进行排序。索引条目的排序支持高效的相等匹配和基于范围的查询操作。此外,MongoDB 还可以使用索引中的顺序来返回排序后的结果。
MongoDB 索引包括默认索引(Default Index)、索引名称和索引构建性能三方面的内容,具体介绍如下:
- 默认索引:MongoDB 数据库在创建集合时,会在 _id 字段上创建一个唯一索引。_id 索引可防止客户端插入两个具有相同_id字段值的文档。同时,设计人员是无法删除该索引的;
- 索引名称:索引的默认名称是索引键和索引中每个键的方向(1 或 -1)的连接,使用下画线作为分隔符。例如,在 {item: 1, quantity: -1} 上创建的索引的名称为 item_1_quantity_-1。另外,索引一旦创建,便无法重命名。如果要重命名索引,就必须删除索引并使用新名称重新创建索引;
- 索引构建性能:应用程序在索引构建期间可能会遭遇性能下降,包括对集合的读/写访问将会受到限制。
MongoDB创建索引
MongoDB 数据库索引支持应用程序在相同字段上重复运行查询,并且可以在这些字段上创建索引以提高查询的性能。如果要在 MongoDB 数据库中创建索引,可以使用 Shell 中的 createIndex() 方法或适用于驱动程序的等效方法。在 MongoDB Shell 或驱动程序中运行创建索引的命令时,MongoDB 仅在没有相同规格索引存在时才会成功创建索引。
同时,尽管在 MongoDB 数据库中创建索引可以提高查询性能,但添加索引会对写入操作的性能产生负面影响。对于具有高写入读取比率的集合,索引的成本很高,因为每次插入和更新还必须更新所有索引。
如果要使用 Node.js 驱动程序创建索引,可以使用 createIndex() 方法:
collection.createIndex({ <key and index type specification> }, function(err, result) { console.log(result); callback(result); });
下面的代码会在 name 字段上创建一个单键降序索引:
collection.createIndex( { name : -1 }, function(err, result) { console.log(result); callback(result); });
若要确认索引已创建,可以使用 mongosh 运行 db.collection.getIndexes() 方法:
db.collection.getIndexes()输出结果如下:
[ { v: 2, key: { _id: 1 }, name: '_id ' }, { v: 2, key: { name: -1 }, name: 'name -1 ' } ]
指定索引名称
MongoDB 数据库在创建索引时,可以为索引指定自定义名称。为索引指定名称有助于区分集合中的不同索引。例如,如果索引具有不同名称,则可以更轻松地在查询计划的解释结果中识别查询使用的索引。想要指定索引名称,可以在创建索引时包含 name 选项,具体代码如下:
db.<collection>.createIndex( { <field>: <value> }, { name: "<indexName>" } )
在指定索引名称之前,需考虑以下几点:
- 索引名称必须是唯一的。使用已有索引的名称创建索引会报错;
- 无法重命名现有索引。相反,必须删除索引并使用新名称重新创建索引。
在下面的应用示例中,博客(Blog)集合包含有关博文与用户交互的数据,在 content、users.comments 和 users.profiles 字段上创建文本索引,同时将索引 name 设置为 InteractionsTextIndex。具体代码如下:
db.blog.createIndex( { content: "text", "users.comments": "text", "users.profiles": "text" }, { name: "InteractionsTextIndex" } )
在创建索引后,可以使用 db.collection.getIndexes() 方法获取索引名称。具体代码如下:
db.blog.getIndexes()输出结果如下:
[ { v: 2, key: { _id: 1 }, name: ' _id ' }, { v: 2, key: { _fts: 'text', ftsx: 1 }, name: 'InteractionsTextIndex', weights: { content: 1, 'users.comments': 1, 'users.profiles': 1 }, default_language: 'english', language_override: 'language', textIndexVersion: 3 } ]
MongoDB删除索引
MongoDB 数据库在删除索引时,可以从集合中删除特定索引。如果发现对性能有负面影响,想用新索引替代特定索引,或者不再需要该索引,则可以删除索引。想要删除索引,可以使用下表所示的 Shell 方法:
方法 | 说明 |
---|---|
db.collection.dropIndex() | 从集合中删除特定索引 |
db.collection.dropIndexes() | 从集合或索引数组中删除所有可移动索引(如果指定) |
设计人员可以删除 _id 字段上的默认索引之外的任何索引,如果要删除 _id 索引,则必须删除整个集合。删除生产环境中频繁使用的索引可能会导致性能下降。在删除索引之前,需要考虑隐藏索引以评估删除索引的潜在影响。
如果要删除索引,则需要知道它的名称。想要获取集合的所有索引名称,可以运行 getIndexes() 方法,具体代码如下:
db.<collection>.getIndexes()
在确定要删除的索引后,需要对指定的集合使用下列一种删除方法,具体说明如下:
1) 删除单个索引。要删除特定索引,可使用 dropIndex() 方法并指定索引名称:
db.<collection>.dropIndex("<indexName>")
2) 删除多个索引。要删除多个索引,可使用 dropIndexes() 方法并指定索引名称数组:
db.<collection>.dropIndexes( [ "<index1>", "<index2>", "<index3>" ] )
3) 删除 _id 索引之外的所有索引。要删除 _id 索引之外的所有索引,可使用 dropIndexes() 方法:
db.<collection>.dropIndexes()在删除索引后,系统返回有关操作状态的信息,输出示例如下:
... { "nIndexesWas" : 3, "ok" : 1 } ...在上面的代码中,nIndexesWas 的值反映了删除索引前的索引数。
想要确认索引已删除,可以运行 db.collection.getIndexes() 方法,具体代码如下:
db.<collection>.getIndexes()删除的索引不再显示在 getIndexes() 输出中。