Download DynamoDBMapper and request

DynamoDBMapper provides various ways to read a single item from a table:

  • Request
  • load

Is there any recommendation which one to use? In a quick test, the following two code fragments return the same "MyEntry" element for a table with primary key = hash and range key = date, while the query method is about 10% faster.

load

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

request

 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); } 
+4
source share
2 answers

Well, now that I'm more used to working with DynamoDB, it turns out that an error in the mapper.query code causes lower performance:

  • "withLimit (1)" does not actually limit the overall results returned in the list, but instead the results are returned to the "PaginatedQueryList" and the actual items are lazily loaded from the database upon access. WithLimit (1) actually limits the items loaded with each request.
  • The actual error is part of "if (storedEntries.size () == 0)", since calling size () actually loads ALL the items in the list. Using the withLimit (1) parameter results in the lowest performance.

The correct code for the mapper request 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); } 
+3
source

Download and query are different operations:

If you have only a hash key scheme, they perform the same operation - retrieve the element with the specified hash key.

If you have a hash range scheme, loading gets a specific element identified by one pair of hashes + range. The request receives all elements that have the specified hash key and satisfy the conditions of the range key.

Since you use the equality operator for both the hash key and the range key, the operations are exactly equivalent.

+3
source

All Articles