DynamoDBMapper加载vs查询



DynamoDBMapper提供了从表中读取一项的不同方法:

    查询
  • <
  • 负载/gh>

是否有建议,使用哪一个?在一个快速测试中,以下两个代码片段为一个主键=hash和范围键=date的表返回相同的"MyEntry"项,而查询方法大约快10%。

<

负载/strong>

public MyEntry getEntryForDay(final Integer hash, final LocalDate date) {
    return mapper.load(MyEntry.class, hash, date);
}
查询

public MyEntry getEntryForDay(final Integer hash, final LocalDate date) {
    final MyEntry hashKeyValues = new MyEntry ();
    hashKeyValues.setHash(hash);
    final Condition rangeKeyCondition = new Condition()//
            .withComparisonOperator(ComparisonOperator.EQ.toString())//
            .withAttributeValueList(new AttributeValue().withS(new LocalDateMarshaller().marshall(date)));
    final DynamoDBQueryExpression<MyEntry> queryExpression = new DynamoDBQueryExpression<MyEntry>()//
            .withHashKeyValues(hashKeyValues)//
            .withRangeKeyCondition("date", rangeKeyCondition)//
            .withLimit(1);
    final List<MyEntry> storedEntries = mapper
            .query(MyEntry.class, queryExpression);
    if (storedEntries.size() == 0) {
        return null;
    }
    return storedEntries.get(0);
}

载入和查询是不同的操作:

如果你有一个只有哈希键的模式,它们会执行相同的操作——用指定的哈希键检索项目。

如果您有一个散列范围模式,load检索由单个散列+范围对标识的特定项。查询检索具有指定哈希键且满足范围键条件的所有项。

由于您对哈希键和范围键都使用了相等运算符,因此操作是完全相等的。

好了,现在我越来越习惯使用DynamoDB,结果发现映射器中的一个bug。查询代码导致性能下降:

  • "withLimit(1)"实际上并没有限制列表中返回的总结果,而是将结果返回到"PaginatedQueryList"中,如果访问,实际项目将从DB惰性加载。WithLimit(1)实际上限制了每个请求加载的项目。
  • 实际的bug是部分"if (storedEntries.size() == 0)",因为size()调用实际上加载列表中的所有项目。使用withLimit(1)将导致最差的性能。

mapper查询的正确代码是:

public MyEntry getEntryForDay(final Integer hash, final LocalDate date) {
    final MyEntry hashKeyValues = new MyEntry ();
    hashKeyValues.setHash(hash);
    final Condition rangeKeyCondition = new Condition()//
            .withComparisonOperator(ComparisonOperator.EQ.toString())//
            .withAttributeValueList(new AttributeValue().withS(new LocalDateMarshaller().marshall(date)));
    final DynamoDBQueryExpression<MyEntry> queryExpression = new DynamoDBQueryExpression<MyEntry>()//
            .withHashKeyValues(hashKeyValues)//
            .withRangeKeyCondition("date", rangeKeyCondition)//
            .withLimit(1);
    final List<MyEntry> storedEntries = mapper
            .query(MyEntry.class, queryExpression);
    if (storedEntries.isEmpty()) {
        return null;
    }
    return storedEntries.get(0);
}

相关内容

  • 没有找到相关文章

最新更新