DynamoDB查询能否按非排序键属性排序?GSI/LSI是否可行?
DynamoDB 查询并按非排序键属性排序的问题解答
原表直接查询的限制
在你给出的表结构(UserId 作为分区键,Type 作为排序键,Timestamp 为普通属性)下,直接通过 UserId 查询并按 Timestamp 排序是做不到的。因为DynamoDB的Query操作返回的结果只能按排序键(SortKey)的顺序排列,无法直接指定其他普通属性作为排序依据。如果硬要实现,只能先把该UserId下的所有数据全部查出来,再在客户端自行排序,但数据量大时这种方式性能差、成本高,完全不推荐。
借助GSI或LSI解决
本地二级索引(LSI)
LSI的分区键必须和主表一致,排序键可以指定其他属性,但存在几个硬限制:
- 只能在创建主表时定义,无法事后添加
- 一张主表最多只能创建5个LSI
- LSI会继承主表的读写容量模式,无法单独配置
如果你的表还未创建,可以考虑构建一个LSI:分区键设为UserId,排序键设为Timestamp。通过这个LSI执行Query操作,就能直接获取该UserId下按Timestamp排序的所有数据。但如果表已创建完成,LSI就无法使用了。
全局二级索引(GSI)
GSI是更灵活的选择,无论表是否已创建都能事后添加:
- 可自定义分区键和排序键,这里可以将
UserId设为GSI的分区键,Timestamp设为GSI的排序键 - GSI拥有独立的读写容量配置,不会影响主表性能
- 查询GSI的方式和主表
Query操作一致,指定UserId作为分区键条件,就能直接获取按Timestamp排序的结果
需要注意的是,GSI是异步同步数据的,存在一定延迟,对实时性要求极高的场景需要评估是否接受该延迟。另外,GSI会额外占用存储和读写资源,需考虑成本。
方案总结
- 若表未创建:可选择LSI(无额外成本但灵活性差)或GSI(灵活但有额外成本)
- 若表已创建:只能通过GSI实现需求
内容的提问来源于stack exchange,提问作者niyruu
相关产品推荐
相关产品推荐

