Amazon DynamoDB
开发人员指南 (API Version 2012-08-10)
AWS 服务或AWS文档中描述的功能,可能因地区/位置而异。请点击 Amazon AWS 入门,可查看中国地区的具体差异

针对 本地二级索引 的最佳实践

本节介绍local secondary index的一些最佳实践。

谨慎使用索引

请勿对不常查询的属性创建local secondary index。对于那些更新频率低,并且通过多个不同条件进行查询的表,创建和维护多个索引才有意义。然而,如果索引被闲置,就会增加存储和 I/O 成本,并且无益于应用程序性能。

因此,对于写入活动工作量很大的表 (例如数据捕获应用程序中使用的表),请避免使用索引。维护索引所需的 I/O 操作成本非常高。如果您需要为此类表中的数据编制索引,请将数据复制到包含必要索引的另外一个表,并对其进行查询。

慎重选择投影

由于local secondary index会占用存储空间和预置吞吐量,因此您应尽可能地减少索引的大小。此外,相较于查询整个表,索引越小,性能优势越明显。如果您的查询通常只返回很少一部分属性,并且这些属性的总和远远少于整个项目的大小,那么您应当只投影经常请求的属性。

如果您预期表中会有大量写入活动 (相较于读取):

  • 请尽量减少投影属性的数量,最大程度减少写入索引的项目大小。但是,如果这些项目比一个写入容量单位 (1 KB) 还要小,则这些项目将不会节省写入容量单位。例如,如果索引条目的大小仅为 200 字节,DynamoDB 就会将其向上取整为 1 KB。也就是说,如果索引项目很小的话,您可以投影更多属性,而不会额外增加成本。

  • 如果您知道在查询中很少用到表的某些属性,就不必投影这些属性。如果您后来更新了索引中没有的属性,将不会因更新索引而额外产生成本。您仍然可以在查询中检索未投影的属性,但是需要的预置吞吐量成本会更高。

只有当您需要让查询返回整个表项目,同时按不同的排序键对表排序时,才应指定 ALL。对所有属性编制索引后就不会再需要表抓取,但在大多数情况下,这样会使得存储和写入活动成本加倍。

优化频繁查询以避免抓取

要在延迟尽可能低的前提下以最快速度完成查询,您可以投影自己认为查询应当会返回的所有属性。如果您查询了某个索引,但是并未投影所请求的属性,那么 DynamoDB 就会从表中抓取所请求的属性。为了实现这一目的,DynamoDB 必须从表中读取整个项目,这样就会带来延迟和产生其他 I/O 操作。

如果您只是偶尔执行某些查询,觉得没必要投影请求的所有属性,这个时候应当注意,这些“偶然”查询经常会转变成“必要”查询!您可能会后悔没有投影这些属性。

有关表抓取的更多信息,请参阅本地二级索引 的预置吞吐量注意事项

利用稀疏索引

只有当项目中存在索引排序键值时,DynamoDB 才会写入相应的索引条目,表中的所有项目都是如此。如果排序键并未出现在每个表项目中,则这种索引称为稀疏索引。

对大多数表项目中都不存在的属性执行查询时,使用稀疏索引很有好处。例如,假如您有一个 CustomerOrders 表,其中存储了您的所有订单,该表的键属性如下所示:

  • 分区键:CustomerId

  • 排序键:OrderId

如果您只想跟踪未结订单,就可以使用名为 IsOpen 的属性。如果您还没收到订单,那么您的应用程序可以通过在表中为该特定项目写入“X” (或任意其他值) 来定义 IsOpen。当订单到达时,您的应用程序可以删除 IsOpen 属性,表示已完成该订单。

要跟踪未结订单,您可以对 CustomerId (分区键) 和 IsOpen (排序键) 创建索引。索引中只会显示表中定义了 IsOpen 的订单。然后,您的应用程序就可以通过查询该索引快速高效地找到相应的未结订单。例如,如果您有数以千计的订单,但是只有少量订单处于未结状态,那么应用程序就可以查询相应的索引,并返回每个未结订单的 OrderId。相较于扫描整个 CustomerOrders 表,您的应用程序执行的读取操作数量将显著减少。

您可以使用不同的属性,以在索引中清晰排序,而不是在 IsOpen 属性中写入任意值。要实现这一目的,您可以创建一个 OrderOpenDate 属性,并将其设置为下订单的日期 (当订单完成时,仍然删除该属性),并且创建具有 CustomerId (分区键) 和 OrderOpenDate (排序键) 架构的 OpenOrders 索引。这样一来,当您查询索引时,系统就会按更清晰的顺序返回项目。

注意扩展项目集合

项目集合是指表中的所有项目及其具有相同分区键的索引。项目集合不能超过 10GB,因此特定的分区键值可能会出现空间不足的情况。

当您添加或更新表项目时,DynamoDB 会更新受影响的所有local secondary index。如果表中定义了索引属性,那么索引会随着表而扩展。

当您创建索引时,请考虑要向索引中写入的数据量,以及有多少数据具有相同的分区键值。如果您预计特定分区键值的表和索引项目之和会超过 10GB,就应考虑是否可以避免创建该索引。

如果不能避免创建此索引,那么您就需要预计项目集合大小限制,并在超过该限制之前采取措施。有关在限制范围内操作以及采取纠正措施的策略,请参阅项目集合大小限制