针对查询和扫描数据的最佳实践
扫描的性能注意事项
一般来说,在 DynamoDB 中,Scan
操作的效率低于其他操作。Scan
操作始终扫描整个表或二级索引。之后,它筛选出值以提供所需结果,从本质上讲,这增加了从结果集中删除数据这个额外步骤。
如有可能,应避免对大型表或索引使用带有会删除很多结果的筛选条件的 Scan
操作。同时,随着表或索引的增大,Scan
操作的速度会变慢。Scan
操作根据请求的值检查每个项目,可以在单次操作中用尽大型表或索引的预置吞吐量。为了缩短响应时间,请对表和索引进行设计,以便应用程序可以使用 Query
而非 Scan
。(对于表,还可以考虑使用 GetItem
和 BatchGetItem
API。)
或者,如果要在应用程序设计中使用 Scan
操作,应最大程度地降低这一操作对您的请求率的影响。
您可以使用以下技巧最大程度地减小扫描操作对表的预置吞吐量的影响,而不使用消耗大量资源的 Scan
操作。
-
减小页面大小
由于扫描操作会读取整个页面(默认情况下为 1 MB),因此,您可以通过设置较小的页面大小来降低扫描操作的影响。您可以使用
Scan
操作提供的 Limit 参数设置请求的页面大小。设置了较小的页面大小后,每个Query
或Scan
请求都会使用更少的读取操作,并会在每个请求之间“停顿”。例如,假设每个项目为 4 KB,并且您将页面大小设置为 40 个项目。之后,Query
请求仅使用 20 次最终一致性读取操作或 40 次强一致性读取操作。如果占用较小容量单位的Query
或Scan
操作数量较多,您就可以成功完成其他重要请求而不会受到限制。 -
隔离扫描操作
DynamoDB 旨在实现轻松可扩展性。因此,应用程序可以创建多个表以彼此区分,甚至多个表可能会复制彼此的内容。您可能会在没有“关键任务型”流量的表中执行扫描。某些应用程序会每小时在两个表之间轮换流量来处理此负载 — 一个用于关键流量,另一个用于计账。其他应用程序可通过让每次写入都在两个表(“关键任务型”表和“影子”表)中执行来实现这一目的。
利用并行扫描
很多应用程序都可以从使用并行 Scan
操作(而非按顺序扫描)中获益。例如,如果要处理含有历史数据的大型表,应用程序并行扫描比按顺序扫描速度快得多。后台“清理程序”进程中的多个工作线程可以对优先级比较低的表进行扫描,而不影响生产流量。在每个示例中,并行 Scan
的使用并不会限制其他应用程序的预置吞吐量资源。
尽管并行扫描比较有利,但是它可能会需要大量预置吞吐量。借助并行扫描,您的应用程序将具有多个工作线程,这些工作线程都同时运行 Scan
操作。这会快速占用表的所有预置读取容量。在这种情况下,需要访问此表的其他应用程序就有可能受到限制。
如果满足以下条件,就可以选择并行扫描:
-
表的大小为 20 GB 或更大。
-
表的预置读取吞吐量尚未完全利用。
-
按顺序执行的
Scan
操作速度过慢。