我在DynamoDB中有一个表,我需要获取前一天的记录列表(在Java中)。它们都具有dateTime属性。
我要引用的表的相关属性: customerUrl(string,hashkey),dateTime(number,range key)和其他一些不相关的属性
我已经尝试用dateTime的哈希键和无范围键设置全局二级索引。该索引名为“ performanceIndex”。然后,我尝试如下查询它:
Map<String, AttributeValue> eav = new HashMap<>();
eav.put(":val1", new AttributeValue().withN(maximumAgeMillis));
DynamoDBQueryExpression<PingLog> pinglogQuery = new DynamoDBQueryExpression<PingLog>();
pinglogQuery.setKeyConditionExpression("dateTime > :val1");
pinglogQuery.setExpressionAttributeValues(eav);
pinglogQuery.setIndexName("performanceIndex");
pinglogQuery.setConsistentRead(false);
List<PingLog> pinglogs = PostDatabaseMapper.getInstance().query(PingLog.class, pinglogQuery);
但是,查询将永久进行并且永不返回。我在其前后添加了一个println语句,并且只有第一个实际打印了。
在执行此查询之前,我只是使用过滤器进行了扫描,并且可以正常工作,但是现在我们有这么多的记录(8000万条),扫描将永远花费下去。我该怎么办?我是否需要其他二级索引?我的查询错了吗?
答案 0 :(得分:0)
您应该使用yyyy-mm-dd
作为分区键,并将hh:mm:ss
作为排序键来创建GSI。 (这可能需要回填整个表,但是如果您经常按日期查询,那将是值得的。)请查看this answer相关问题,其中有关于此方法的更多详细信息。
根据您所拥有的数据访问方式的种类,可能会出现复杂的情况。它是相当稳定的还是爆发性的?当前项目的写入吞吐量是否会比其他任何一天高?
如果您要处理时间序列数据(例如IoT传感器读数),则此策略可能对您不起作用。您的GSI中可能有一个热分区,这可能会使主表产生反压并导致写入受到限制。由于DynamoDB的自适应能力,这种情况不太可能出现,但有可能。
在这种情况下,您应该考虑DynamoDB推荐的best practice for handling time-series data。它讨论了如何处理随时间推移具有不同访问要求的数据。他们的解决方案的要旨是为每个时间段(天/月/年/任何时间)创建单独的表,以便来自不同时间范围的数据可以具有不同的预配置容量。