

# DynamoDB 中二级索引的一般指导原则
<a name="bp-indexes-general"></a>

Amazon DynamoDB 支持两种的二级索引：
+ **全局二级索引（GSI）** – 索引的分区键和排序键可与基表不同。全局二级索引之所以称为“全局”，是因为索引上的查询可跨过所有分区，覆盖基表的所有数据。全局二级索引没有大小限制，有自己的预置读取写入吞吐量设置，与表不同。
+ **本地二级索引（LSI）** – 索引的分区键与基表相同，但排序键不同。本地二级索引之所以称为“本地”，是因为索引的每个分区的范围都限定为具有相同分区键值的基表分区。因此，任何一个分区键值的索引项目总大小不得超过 10 GB。此外，本地二级索引与其索引的表共享预置的读写吞吐量设置。

DynamoDB 每个表最多可以具有 20 个全局二级索引（默认配额）和 5 个本地二级索引。

全局二级索引通常比本地二级索引更有用。确定要使用哪种类型的索引还将取决于您的应用程序的要求。有关全局二级索引和本地二级索引的比较以及有关如何在二者之间进行选择的更多信息，请参阅[在 DynamoDB 中使用二级索引改进数据访问](SecondaryIndexes.md)。

在 DynamoDB 中创建索引时要记住的一些一般原则和设计模式如下：

**Topics**
+ [高效使用索引](#bp-indexes-general-efficiency)
+ [慎重选择投影](#bp-indexes-general-projections)
+ [优化频繁查询以避免获取](#bp-indexes-general-fetches)
+ [创建本地二级索引时注意项目集合大小限制](#bp-indexes-general-expanding-collections)

## 高效使用索引
<a name="bp-indexes-general-efficiency"></a>

**尽可能减少索引数量。**不要对不常查询的属性创建二级索引。很少使用的索引会增加存储和 I/O 成本，无法提高应用程序性能。

## 慎重选择投影
<a name="bp-indexes-general-projections"></a>

二级索引占用存储空间和预调配吞吐量，应尽可能减小索引。此外，索引越小，相比查询整个表的性能优势越明显。如果查询通常只返回很少一部分属性，并且这些属性的总和远小于整个项目，则应只投影经常请求的属性。

如果预计表有大量写入操作（相比读取），请遵循以下最佳实践：
+ 考虑减少投影属性的数量，尽可能减少写入索引的项目大小。但是，这只适用于投影属性的大小大于单个写入容量单位 (1 KB) 的情况。例如，如果索引条目的大小仅为 200 字节，则 DynamoDB 将向上取整为 1 KB。也就是说，如果索引项目很小，可以投影更多属性，而不会额外增加成本。
+ 避免投影查询中极少需要的属性。每次更新索引中投影的属性时，将产生更新索引的额外成本。仍然可以以较高的预调配吞吐量成本检索 `Query` 中的未投影属性，但查询成本明显低于频繁更新索引的成本。
+ 仅当需要查询返回按不同排序键排序的整个表项目时，指定 `ALL`。投影所有属性将无需表获取，但在大多数情况下，存储和写入操作成本将加倍。

下一节介绍在保证索引尽可能小，与保证获取操作尽可能少的需求之间取得平衡。

## 优化频繁查询以避免获取
<a name="bp-indexes-general-fetches"></a>

要实现最快查询并且延迟最低，可以投影预计查询将返回的所有属性。具体而言，如果对没有投影的属性查询本地二级索引，DynamoDB 将自动从表获取这些属性，这需要从表读取整个项目，带来本可避免的延迟和额外 I/O 操作。

请记住，这些“偶尔”查询经常会转变成“必要”查询。如果预计仅仅偶尔查询，所以计划不投影某些属性，请考虑是否情况可能改变，后悔没有投影这些属性。

有关表获取的更多信息，请参阅 [全局二级索引的预调配吞吐量注意事项](LSI.md#LSI.ThroughputConsiderations)。

## 创建本地二级索引时注意项目集合大小限制
<a name="bp-indexes-general-expanding-collections"></a>

*项目集合*指表的所有项目及其具有相同分区键的本地二级索引。项目集合不能超过 10 GB，因此特定的分区键值可能会出现空间用尽的情况。

添加或更新表项目时，DynamoDB 会更新受影响的所有本地二级索引。如果表中定义索引属性，本地二级索引也会增长。

创建本地二级索引时，考虑将写入的数据量，以及具有相同分区键值的数据项目数量。如果预计特定分区键值的表和索引项目总和可能超过 10 GB，请考虑是否应避免创建索引。

如果无法避免创建本地二级索引，则必须预计项目集合大小限制，并在超过限制前采取措施。作为最佳实践，在写入项目时应使用 [https://docs.amazonaws.cn/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/model/ReturnItemCollectionMetrics.html](https://docs.amazonaws.cn/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/model/ReturnItemCollectionMetrics.html) 参数来监控接近 10 GB 大小限制的项目集大小并发出警报。超过最大项目集大小将导致写入尝试失败。您可以在项目集大小尚未对应用程序造成影响前，对其进行监控并发出警报，以此来缓解项目集大小问题。

**注意**  
创建后，您无法删除本地二级索引。

有关在限制范围内操作以及采取纠正措施的策略，请参阅 [项目集合大小限制](LSI.md#LSI.ItemCollections.SizeLimit)。