使用排序键子集的L/GSI替代begins_with()是否具备优势?
用排序键子集的L/GSI替代begins_with()查询的优劣势分析
针对你提到的场景——主表排序键由a、b、c复合而成,频繁执行已知a和b值的查询,下面从效率和成本两方面对比两种方案:
效率对比
- L/GSI方案更高效:
主表用begins_with()查询时,DynamoDB需要扫描所有匹配a+b+*前缀的排序键条目,属于范围扫描操作。而如果创建以a+b为核心的L/GSI(比如将主表分区键+a+b作为GSI的主键),查询时可以通过精确匹配直接定位目标数据,属于点查询或高效主键查询,延迟更低、吞吐量利用率更高。尤其当a+b对应的c值条目数量较多时,这种效率差异会非常明显。 - 一致性选项:主表的
begins_with()查询天然支持强一致性读取;GSI默认是最终一致性,但也可以配置强一致性读取,能满足多数业务的一致性需求。
成本对比
- 存储成本:L/GSI会复制主表的部分或全部数据(取决于投影属性配置),因此会产生额外的存储费用。如果投影大量属性,存储成本的增长会更显著,而主表查询无需额外存储开销。
- 读写成本:
- 写入阶段:主表的每一次增删改操作,都会同步触发L/GSI的更新,因此会额外消耗GSI的写入容量单位,写入成本更高。
- 读取阶段:GSI的精确查询消耗的读取容量单位远低于主表
begins_with()的范围扫描(范围扫描按扫描到的条目数计算读取单位)。当a+b对应的c值条目越多,GSI的读取成本优势就越突出。
决策建议
如果这个已知a+b的查询是高频场景,且对应的c值条目数量较多,那么创建L/GSI在长期的读取效率和读取成本上会更具优势,额外的存储和写入成本可以被高频查询的收益抵消;如果查询频率不高,或者a+b对应的c值条目极少,那么直接使用主表的begins_with()更划算,无需承担GSI的额外开销。
内容的提问来源于stack exchange,提问作者Sonny
相关产品推荐
相关产品推荐

