Reputation: 2855
The DynamoDBMapper provides different ways to read one item from a table:
Is there a recommendation, which of them to use? In a quick test, the following two code snippets return the same "MyEntry" item for a table with primary key=hash and range key=date, whereas the query method is roughly 10% faster.
load
public MyEntry getEntryForDay(final Integer hash, final LocalDate date) {
return mapper.load(MyEntry.class, hash, date);
}
query
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);
}
Upvotes: 22
Views: 29667
Reputation: 2855
Ok, now as I'm getting more used to work with DynamoDB it turns out that a bug in the mapper.query code is causing the poorer performance:
The correct code for the mapper query is:
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);
}
Upvotes: 7
Reputation: 1756
Load and Query are different operations:
If you have a hash key only schema, they perform the same operation - retrieve the item with the hash key specified.
If you have a hash-range schema, load retrieves a specific item identified by a single hash + range pair. Query retrieves all items that have the specified hash key and meet the range key conditions.
Since you are using the equality operator for both the hash key and range key, the operations are exactly equivalent.
Upvotes: 25