

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 管理 Amazon DocumentDB 索引
管理索引

**Topics**
+ [

## Amazon DocumentDB 索引创建
](#index-creation)
+ [

## 维护 Amazon DocumentDB 索引
](#maintaining-indexes)

## Amazon DocumentDB 索引创建


在 Amazon DocumentDB 中创建索引需要做出一些决定：
+ 需要多久完成？
+ 在构建过程中无法访问该集合吗？
+ 一个实例的计算能力有多少可以分配给构建？
+ 应该创建什么类型的索引？

本节将帮助您回答这些问题，并提供用于在基于实例的集群集合上创建 Amazon DocumentDB 索引的命令和监控示例。

### 指南要求


以下指南包括创建新索引时的基本限制和配置权衡：
+ **Amazon DocumentDB 版本支持** – 虽然所有版本的 Amazon DocumentDB 都支持单工作进程索引，但只有 Amazon DocumentDB 版本 4.0 和 5.0 支持多工作进程索引。
+ **性能权衡** - 在索引创建过程中增加工作进程数量会增加 Amazon DocumentDB 数据库主实例上的 CPU 利用率和读取 IO。创建新索引所需的资源将无法用于正在运行的工作负载。
+ **弹性集群** - Amazon DocumentDB 弹性集群不支持并行索引。
+ **最大工作进程** - 您可以配置的最大工作进程取决于数据库集群中主实例的大小。它是数据库集群主实例CPUs 上 v 总数的一半。例如，在具有 64 v 的 db.r6g.16xlarge 实例上，你最多可以运行 32 个工作程序。CPUs
**注意**  
2xlarge 及更低版本的实例类不支持并行工作进程。
+ **最少工作进程** - 您可以配置的最小工作进程为 1。在基于实例的集群上创建索引的默认设置是两个工作进程。但是，您可以使用“工作线程”选项将工作进程减少到一个。这将使用单工作进程运行该进程。
+ **索引压缩** - Amazon DocumentDB 不支持索引压缩。索引的数据大小可能比您使用其他选项时更大。
+ **索引多个集合**-数据库集群主实例CPUs 上的 v 的一半可用于配置好的工作线程对多个集合执行索引创建。
+ **索引类型** - 有关 Amazon DocumentDB 上支持的索引类型的完整说明，请参阅[此博客文章](https://www.amazonaws.cn/blogs/database/how-to-index-on-amazon-documentdb-with-mongodb-compatibility/)。

### 开始使用


要开始在集合上创建索引，请使用 `createIndexes` 命令。默认情况下，该命令将运行两个并行工作进程，可将索引创建过程的速度提高两倍。

例如，以下命令过程演示了如何为文档中的 “user\$1name” 字段创建索引，并将索引处理速度提至四个工作进程：

1. 在集群上使用两个并行工作进程创建索引：

   ```
   db.runCommand({"createIndexes":"test","indexes":[{"key": {"user_name":1}, "name":"username_idx"}]})
   ```

1. 要优化索引创建过程的速度，您可以使用 `db.runCommand createIndexes` 命令中的“工作线程”选项（`"workers":<number>`）指定工作进程数。

   将处理速度提至四个并行工作进程：

   ```
   db.runCommand({"createIndexes":"test","indexes":[{"key": {"user_name":1}, "name":"username_idx", "workers":4}]})
   ```
**注意**  
工作进程数越多，则索引创建速度越快。但是，工作线程数量增加得越多，主实例的 v CPUs 和读取 IO 的负载增加就越大。确保您的集群配置充足，足以应对增加的负担，不会使其他工作负载降级。

### 索引进度状态


索引创建过程的工作原理是初始化、扫描集合、排序键，最后通过索引生成器插入键。在前台运行时，该过程最多有六个阶段，在后台运行时，则最多有九个阶段。您可以逐阶段查看状态指标，例如完成百分比、扫描的存储块总数、已排序键和已插入键。

使用 mongo Shell 中的`db.currentOp()`命令监控索引过程进度。最后一个阶段的 100% 已完成表示所有索引都已成功创建：

```
db.currentOp({"command.createIndexes": { $exists : true } })
```

**注意**  
仅支持在 Amazon DocumentDB 5.0 上查看索引进度状态。

#### 索引构建类型


索引构建的四种类型是：
+ **前台** – 在创建索引之前，前台索引构建将阻止所有其他数据库操作。Amazon DocumentDB 前台构建由五个阶段组成。
+ **前台（唯一）**– 单个文档（唯一）前台索引构建将阻止其他数据库操作，例如常规前台构建。与基本前台构建不同，唯一构建使用额外的阶段（排序键 2）来查找重复的键。前台（唯一）构建由六个阶段组成。
+ **后台** – 后台索引构建允许创建索引时在前台运行其他数据库操作。Amazon DocumentDB 后台构建由八个阶段组成。
+ **后台（唯一）**– 单个文档（唯一）后台索引构建允许在创建索引时在前台运行其他数据库操作。与基本背景构建不同，唯一构建使用额外的阶段（排序键 2）来查找重复的键。后台（唯一）构建由九个阶段组成。

#### 索引构建阶段



| 舞台 | 前台 | 前台（唯一） | 背景 | 背景（唯一） | 
| --- | --- | --- | --- | --- | 
|  INITIALIZING  |  1  |  1  |  1  |  1  | 
|  构建索引：初始化  |  2  |  2  |  2  |  2  | 
|  构建索引：扫描集合  |  3  |  3  |  3  |  3  | 
|  构建索引：排序键 1  |  4  |  4  |  4  |  4  | 
|  构建索引：排序键 2  |    |  5  |    |  5  | 
|  构建索引：插入键  |  5  |  6  |  5  |  6  | 
|  验证：扫描索引  |    |    |  6  |  7  | 
|  验证：排序元组  |    |    |  7  |  8  | 
|  验证：扫描集合  |    |    |  8  |  9  | 
+ **正在初始化** - createIndex 正在准备索引生成器。该阶段应该非常短暂。
+ **构建索引：正在初始化** - 索引生成器正在准备创建索引。该阶段应该非常短暂。
+ **构建索引：扫描集合** - 索引生成器正在执行集合扫描以收集索引秘钥。测量单位是“块”。
**注意**  
如果为索引构建配置了多个工作进程，则在此阶段将显示该工作进程。“扫描集合”阶段是在索引构建过程中使用多个工作进程的唯一阶段。所有其他阶段将显示单工作进程。
+ **构建索引：排序键 1** - 索引生成器正在排序已收集的索引键。测量单位是“键”。
+ **构建索引：排序键 2** - 索引生成器正在对收集的与死元组相对应的索引键进行排序。此阶段仅适用于唯一索引构建。测量单位是“键”。
+ **构建索引：插入键** - 索引生成器正在将索引键插入到新索引中。测量单位是“键”。
+ **验证：扫描索引** - createIndex 正在扫描索引以查找需要验证的键。测量单位是“块”。
+ **验证：排序元组** - createIndex 正在排序索引扫描阶段的输出。
+ **验证：扫描集合** - CreateIndex 正在扫描集合以验证在前两个阶段中找到的索引键。测量单位是“块”。

#### 索引构建输出示例


在如下输出示例（前台索引构建）中，显示了索引创建的状态。“msg”字段通过指示构建的阶段和完成百分比来汇总构建进度。“工作进程”字段表示在该索引构建阶段使用的工作进程数。“进度”字段显示用于计算完成百分比的实际数字。

**注意**  
亚马逊 DocumentDB 版本 4.0 不支持 “currentIndexBuild姓名”、“消息” 和 “进度” 字段。

```
{
    "inprog" : [{
    … 
        "command": {
            "createIndexes": "test",
            "indexes": [{
                "v": 2,
                "key": {
                    "user_name": 1
                },
                "name": "user_name_1"
            }],
            "lsid": {
                "id": UUID(“094d0fba-8f41-4373-82c3-7c4c7b5ff13b”)
            },
            "$db": "test"
        },
        "currentIndexBuildName": user_name_1,
        "msg": "Index Build: building index number_1, stage 6/6 building index: 656860/1003520 (keys) 65%",
        "workers": 1,
        "progress": {
            "done": 656861,
            "total": 1003520
        },
    … 
    ],
 
    "ok" : 1
}
```

## 维护 Amazon DocumentDB 索引


**Topics**
+ [

### 索引膨胀
](#db-index-bloat)
+ [

### 使用 `reIndex` 进行索引维护
](#reIndex)

### 索引膨胀


Amazon DocumentDB 使用多版本并发控制（MVCC）来管理并发事务。删除或更新文档后，其先前版本将作为“失效”版本保留在集合和索引中。垃圾回收过程会自动从这些失效版本中回收空间以用于未来的操作。

当集合的索引因失效或过时的索引条目累积或页面内的碎片累积而变大时，就会出现索引膨胀。报告的百分比表示未来索引条目可以使用的索引空间量。此膨胀会同时消耗缓冲区缓存和存储空间中的空间。如果要消除膨胀，则需要重建索引。

**Example 示例**  
运行以下命令以确定索引未使用的存储空间：  

```
db.coll.aggregate({$indexStats:{}});
```
结果类似如下：  

```
{ 
    "name" : "_id_",
    "key" : { 
        "_id" : 1 
    },
    "host" : "devbox-test.localhost.a2z.com:27317",
    "size" : NumberLong(827392),
    "accesses" : {
        "ops" : NumberLong(40000),
        "docsRead" : NumberLong(46049),
        "since" : ISODate("2025-04-03T21:44:51.251Z") 
    },
    "cacheStats" : {
        "blksRead" : NumberLong(264),
        "blksHit" : NumberLong(140190),
        "hitRatio" : 99.8121
    }, 
    "unusedStorageSize" : {
        "unusedSizeBytes" : 409600,
        "unusedSizePercent" : 49.51
    }
}
```

使用 `reIndex` 命令无需停机即可重建索引，该命令需要扫描整个集合。请参阅[使用 `reIndex` 进行索引维护](#reIndex)。

### 使用 `reIndex` 进行索引维护


`reIndex` 是用于重建索引的命令。通常在索引损坏或效率低下时使用。随着时间的推移，索引会因为多次更新、插入或删除而积累未使用的空间，从而导致性能下降。重新编制索引有助于删除此类未使用的空间并恢复索引的效率。

#### `reIndex` 准则

+ `reIndex` 目前仅在 Amazon DocumentDB 5.0 上受支持。
+ Amazon DocumentDB 支持在后台进行单个索引的 `reindex`，以便多个工作人员操作。在 `reIndex` 程序运行时，查询可以使用旧索引。
+ Amazon DocumentDB 支持通过 `currentOp` 发布索引进度报告。您可以看到与创建索引时看到的 [索引构建阶段](#index-build-stages) 类似的索引构建阶段。唯一的区别是 `reIndex` 始终有八个阶段，无论它是否唯一。没有“构建索引：排序键 2”阶段。
+ `reIndex` 可以与同一个集合上的任何命令同时运行，但与索引相关的下列命令除外：`createIndexes`、`dropIndexes`、`collMod` 和 `renameCollection`。
+ `reIndex` 目前不支持文本索引、地理空间索引、向量索引和部分索引。

##### `reIndex` 构建


使用以下命令来重建索引：

```
db.runCommand({ reIndex: "collection-name", index: "index-name"})
```

您也可以选择控制分配给重建过程的工作人员的人数：

```
db.runCommand({ reIndex: "collection-name", index: "index-name", workers: number })
```