Java (AWS SDK v2) ile DynamoDB Scan
scanPaginator, LastEvaluatedKey'i sizin yerinize halleder ve çoğu kişinin bir sonraki adımda uzandığı tek düğme — .limit(...) — aynı taramayı daha yavaş ve biraz daha pahalı hâle getirir. Scan'den bütünüyle ne zaman kaçınmanız gerektiği için bkz. Query ile Scan karşılaştırması.
Kod
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.ScanRequest;
import software.amazon.awssdk.services.dynamodb.model.ScanResponse;
public class ScanExample {
public static void main(String[] args) {
try (DynamoDbClient ddb = DynamoDbClient.builder()
.region(Region.US_EAST_1)
.build()) {
Map<String, String> names = new HashMap<>();
names.put("#filter0", "Year");
Map<String, AttributeValue> values = new HashMap<>();
values.put(":filterValue0", AttributeValue.builder().n("2010").build());
ScanRequest request = ScanRequest.builder()
.tableName("Music")
.filterExpression("#filter0 >= :filterValue0")
.expressionAttributeNames(names)
.expressionAttributeValues(values)
.build();
List<Map<String, AttributeValue>> items = new ArrayList<>();
for (ScanResponse page : ddb.scanPaginator(request)) {
items.addAll(page.items());
}
System.out.println("Matched " + items.size() + " items");
} catch (DynamoDbException e) {
System.err.println(e.getMessage());
}
}
}.limit(25) 3 isteği 25'e çevirir ve daha pahalıya mal olur
Düzenek, her biri kabaca 3,9 KB olan 600 şarkı tutuyor ve bunların 8'i eşleşiyor. Örneği yazıldığı gibi çalıştırın, sonra .limit(25) ile yeniden çalıştırın:
| İstek biçimi | Gidiş-dönüş | Okuma birimi | Döndürülen öğe |
|---|---|---|---|
| yazıldığı gibi | 3 | 284,5 | 8 |
.limit(25) | 25 | 288,0 | 8 |
Kapasite sayfa başına, 4 KB sınırına yukarı yuvarlanarak faturalandırılır; dolayısıyla 1 MB'lık tek bir okumayı 24 küçük okumaya bölmek yuvarlamayı 24 kez öder. 25. istek diğer sürprizdir: 24. sayfa tabloyu bitirdi ve yine de bir LastEvaluatedKey döndürdü, dolayısıyla sayfalayıcı bir kez daha sordu ve scannedCount=0 aldı. DynamoDB "başka veri yok" sinyalini kısa bir sayfa döndürerek değil, o anahtarı atlayarak verir ve bir Limit sınırında bunu henüz bilmez.
.limit(...), canlı bir tabloyu kısıtlamasını istemediğiniz bir arka plan işi için bir kapasite yumuşatma düğmesidir. Bir taramayı ucuzlatmanın ya da kısaltmanın yolu değildir.
Takma ad biçimsel değildir
#filter0'ı bırakıp doğrudan Year üzerinde filtreleyin; SDK bunu awsErrorDetails() üzerinden yüzeye çıkarır:
DynamoDbException / ValidationException /
Invalid FilterExpression: Attribute name is a reserved keyword; reserved keyword: Year
/ http 400Year, 573 ayrılmış sözcükten biridir. Bu SDK'daki her sayfalayıcı hatası gibi o da scanPaginator(request) çağırdığınızda değil, for döngüsünün ilk yinelemesinde gelir; dolayısıyla try'ın döngüyü sarması gerekir.
2026-07-28 tarihinde OpenJDK 26.0.1 üzerinde software.amazon.awssdk:dynamodb 2.49.4 ile DynamoDB Local'a (amazon/dynamodb-local) karşı ölçüldü.
Açıklama
- İlk iki sayfa sıfır öğe döndürür. Bu filtreyle sayfa başına sonuçlar 0, 0 ve 8'dir; sırasıyla 128,5, 128,5 ve 27,5 okuma birimiyle.
filterExpressionokumadan sonra çalışır, dolayısıyla o iki boş yanıt tam fiyata mal olur ve herhangi birif (page.items().isEmpty()) break, boş bir tablo bildirir. ddb.scanPaginator(request).items(), sayfaları tek birIterable<Map<String, AttributeValue>>içinde düzleştirir ve arkanızda sayfalar; yalnızca öğeleri istediğinizde iç içe döngüyü ortadan kaldırır. BirSdkIterable'dır, dolayısıyla.stream()çalışır —.items().stream().count()burada 8 döndürür.ScanIterableher yinelemede taramayı yeniden çalıştırır. Tembeldir, önbelleklenmiş değil: aynı nesne üzerinde iki kez dönmek istekleri iki kez gönderir ve iki kez faturalandırır. Örneğin yaptığı gibi onu bir kez birList'e boşaltın.- Oluşturucuda sayılar
String'dir.AttributeValue.builder().n("2010")birjava.lang.Stringalır, çünkü DynamoDB sayıları ondalık metin olarak taşır. Birintgeçirmek derlenmez. .segment(...)/.totalSegments(...), tam tablo taramasını her biri kendi sayfalayıcısına sahip işçilere böler. Bu, duvar saati süresini böler ve aynı kapasiteyi harcar.
Görsel olarak yapın
Ayrılmış sözcük denetleyicisi öznitelik adlarınızı tam AWS listesine karşı çalıştırır ve size ExpressionAttributeNames haritasını verir; bu, Year, Name, Size ve Status'ün hepsinin alınmış olduğunu her seferinde bir ValidationException ile öğrenmekten hızlıdır.
Bir filtreyi bir ScanRequest içine kablolamadan önce gerçek bir tabloya karşı denemek için DynoTable'ı indirin ve sonuçları bir ızgarada sayfalayın.
İlgili örnekler
- Go ile DynamoDB Scan — aynı tarama, AWS SDK for Go v2 ile.
- Java ile DynamoDB Query — genellikle uzanmanız gereken daha ucuz okuma.
- Query ile Scan karşılaştırması — bir
Scan'in (nadiren) ne zaman gerekçelendirilebildiği. - DynamoDB Scan'im neden yavaş ve pahalı? — maliyet modeli ve ondan nasıl kaçınılacağı.
- DynamoDB ProvisionedThroughputExceededException — tam tablo taramasının sağlanan kapasiteli bir tabloya ne yaptığı.
- DynamoDB ThrottlingException — diğer kısıtlama ve üstel geri çekilmenin onu nasıl ele aldığı.
Kaynaklar
- Scan — Amazon DynamoDB API Reference
- Use Scan with an AWS SDK or CLI — Amazon DynamoDB Developer Guide
- DynamoDbClient — AWS SDK for Java 2.x API Reference
- ScanRequest — AWS SDK for Java 2.x API Reference
- Scanning tables — Amazon DynamoDB Developer Guide
- Reserved words in DynamoDB — Amazon DynamoDB Developer Guide