Cara COUNT, SUM, dan Agregasi di DynamoDB
DynamoDB memiliki tepat satu agregat bawaan: menghitung Item yang cocok dengan
Select=COUNT. Tidak ada SUM, AVG, MIN, atau MAX native. Dan bahkan count
yang bisa Anda dapatkan membaca (dan menagih) setiap Item yang dihitungnya.
Panduan ini mencakup apa yang sebenarnya didukung, pendekatan yang biasa diandalkan
orang, dan cara menjalankan COUNT/SUM/AVG sungguhan atas sebuah tabel saat
Anda membutuhkannya.
Bisakah DynamoDB melakukan SUM, COUNT, dan fungsi agregat?
Sebagian besar tidak. Satu-satunya agregat bawaan DynamoDB adalah Select=COUNT, yang mengembalikan jumlah Item yang cocok tetapi tetap membaca (dan menagih) setiap Item. Tidak ada SUM, AVG, MIN, atau MAX native, dan PartiQL juga tidak menambahkannya. Untuk agregat sungguhan dengan GROUP BY, lipat di aplikasi Anda, pelihara sebuah counter, atau jalankan SQL di SQL Workbench DynoTable.
Select=COUNTmengembalikan jumlah Item yang cocok, tetapi DynamoDB tetap membaca setiap Item untuk menghasilkannya — Anda membayar biaya pembacaanScan/Querypenuh, bukan biaya "count" yang murah.- Tidak ada
SUM,AVG,MIN, atauMAXnative. Operasi pembacaan DynamoDB mengembalikan Item; ia tidak melipatnya menjadi sebuah angka. PartiQL juga tidak menambahkan agregat. DescribeTable.ItemCountgratis tetapi perkiraan dan diperbarui hanya "kira-kira setiap enam jam" — baik untuk ubin dashboard, salah untuk apa pun yang harus persis.- Untuk
COUNT/SUM/AVG/MIN/MAXyang persis (denganGROUP BY), agregasikan di aplikasi Anda, pelihara sebuah counter, atau jalankan di SQL Workbench DynoTable (di bawah).
Menghitung Item: Select=COUNT
Baik Query maupun Scan menerima parameter Select. Setel ke COUNT dan respons
membawa jumlah alih-alih Item:
aws dynamodb scan \
--table-name Orders \
--select COUNT \
--filter-expression "#s = :open" \
--expression-attribute-names '{"#s":"status"}' \
--expression-attribute-values '{":open":{"S":"OPEN"}}'Respons memberi Anda dua angka (AWS: Counting the items in the results):
Count— "the number of items that remain, after a filter expression (if present) was applied."ScannedCount— "the number of items evaluated, before anyScanFilteris applied." Tanpa filter,ScannedCountsama denganCount.
Jika Anda hanya punya partition key dan perlu menghitung duplikat di dalamnya,
condition + filter yang Anda berikan persis seperti yang dihasilkan
DynamoDB Expression Builder — map
KeyConditionExpression, FilterExpression, dan ExpressionAttributeNames/Values
di atas — tanpa meng-escape JSON secara manual.
Dua jebakan lagi yang menggigit orang yang menghitung tabel besar:
- Batas halaman 1 MB tetap berlaku. "If the size of the
Scanresult set is larger than 1 MB,ScannedCountandCountrepresent only a partial count of the total items" (dokumen AWS Scan). Anda harus melakukan paginasi denganLastEvaluatedKey→ExclusiveStartKeydan menyimpan total berjalan untuk mendapatkan angka yang sebenarnya — loop yang sama yang dibahas di paginasi DynamoDB. Queryyang sempit mengalahkanScan.Select=COUNTpada sebuahQueryhanya mengukur Item di partisi yang ditargetkan, bukan seluruh tabel. Jika Anda dapat menyematkan sebuah partition key (tabel dasar atau sebuah GSI), hitung di sana — itulah celah biaya Query-vs-Scan yang diterapkan pada penghitungan.
Select=COUNT vs ItemCount (dan mengapa ia basi)
DescribeTable mengembalikan sebuah ItemCount (dan TableSizeBytes) secara
gratis, tanpa biaya pembacaan. Tangkapannya ada di
referensi API itu sendiri:
"DynamoDB updates this value approximately every six hours. Recent changes might not
be reflected in this value." Jadi ia bisa tertinggal jauh di belakang kondisi
sebenarnya tabel Anda.
Select=COUNT | DescribeTable.ItemCount | |
|---|---|---|
| Ketepatan | Persis (untuk set yang cocok) | Perkiraan |
| Kesegaran | Live | Diperbarui ~setiap 6 jam |
| Biaya | Membaca + menagih setiap Item yang dihitung | Gratis (metadata) |
| Bisa filter / hitung subset | Ya (filter expression) | Tidak — hanya seluruh tabel |
Gunakan ItemCount untuk pengecekan kasar "seberapa besar tabel ini" atau ubin
dashboard. Gunakan Select=COUNT saat Anda butuh angka yang persis, terfilter, atau
terkini — dan terima biaya pembacaannya. Untuk apa pun yang benar-benar live dan
gratis, lacak sebuah counter sendiri (lihat Pola agregasi di bawah).
Mengapa tidak ada SUM/AVG/MIN/MAX native
Operasi pembacaan DynamoDB mengembalikan Item. Tidak ada query planner untuk melipat
sebuah result set menjadi skalar, jadi tidak ada apa pun untuk menghitung sebuah
SUM atau AVG. Penghitungan adalah satu-satunya lipatan yang ditawarkan API,
melalui Select=COUNT.
PartiQL tidak mengubah ini. Grammar SELECT
PartiQL
adalah SELECT {{expression}} [, …] FROM {{table}}[.{{index}}] [WHERE …] [ORDER BY {{key}} …],
di mana expression adalah "a projection formed from the * wildcard or a projection
list of one or more attribute names or document paths." Tidak ada fungsi agregat dan
tidak ada klausa GROUP BY dalam grammar itu — dan ORDER BY menerima sebuah
{{key}}, yang didokumentasikan sebagai "a hash key or a sort key to use to order
returned results." Setiap SELECT PartiQL tetap dikompilasi menjadi sebuah
GetItem, Query, atau Scan, jadi SELECT SUM(total) FROM "Orders" sama sekali
tidak dapat dinyatakan. (Lebih lanjut tentang langit-langit PartiQL di
PartiQL vs SQL.)
Pola agregasi (counter, stream, sisi-aplikasi)
Karena DynamoDB tidak akan mengagregasi untuk Anda, pola yang mapan mendorong pekerjaan itu ke tempat lain:
- Item counter terpelihara. Pelihara sebuah Item khusus (mis.
PK = "STATS#orders") danADDke sebuah atribut numerik pada setiap penulisan dengan sebuahUpdateItem. Membaca agregatnya kemudian adalah sebuahGetItemtunggal — persis dan murah, tetapi Anda memiliki logika penambahan, konsistensinya, dan contention jika satu counter dihantam terus-menerus. - DynamoDB Streams → agregator. Aktifkan sebuah stream dan sambungkan ke sebuah
Lambda yang memperbarui total berjalan (count, sum) saat Item berubah. Sesuai
dokumen AWS Streams,
Anda dapat mengonfigurasi
StreamViewTypestream sehingga setiap rekaman membawaNEW_AND_OLD_IMAGES— "both the new and the old images of the item" — cukup untuk menjaga agregat gaya-SUMtetap terkini tanpa men-scan ulang. Rekaman stream tunduk pada masa hidup 24 jam ("the stream records within a shard are removed automatically after 24 hours"), jadi konsumernya harus mengimbangi. - Lipatan sisi-aplikasi. Lakukan paginasi melalui Item yang cocok dan akumulasi
SUM/AVG/MIN/MAXdi kode Anda sendiri. Benar, tetapi ia membaca (dan menagih) setiap Item setiap kali — profil biaya yang sama denganSelect=COUNT, ditambah transfer datanya. - Alihkan ke analitik. Untuk agregasi analitis yang berat atau ad-hoc, ekspor tabel ke S3 dan query dengan Athena, atau alirkan ke sebuah warehouse. Sesuai dokumen AWS ekspor-ke-S3, mengekspor "doesn't consume read capacity units" dan memungkinkan Anda "perform analytics and complex queries using AWS services such as Athena" — jalur yang direkomendasikan AWS begitu Anda melampaui agregasi per-request.
Masing-masing menukar kesederhanaan dengan entah pembukuan saat-penulisan (counter,
stream) atau biaya saat-pembacaan (scan sisi-aplikasi). Tidak ada pola yang membuat
DynamoDB sendiri menghitung sebuah SUM secara gratis. Versi pengelompokan dari
tradeoff ini — mengagregasi per key alih-alih atas seluruh tabel — adalah panduan
tersendiri: DynamoDB GROUP BY.
Menjalankan COUNT/SUM/AVG di SQL Workbench DynoTable
Ketika Anda hanya butuh jawabannya — "berapa banyak order OPEN, dan berapa totalnya" — tanpa menulis loop scan berpaginasi atau sebuah Lambda, SQL Workbench DynoTable menjalankan agregat sungguhan. Ia memmaterialisasi tabel Anda melalui runtime Query/Scan DynamoDB yang sebenarnya, lalu menjalankan SQL Anda sepenuhnya di atasnya: SQL dalam aturan pola akses DynamoDB.
-- Runs in the DynoTable Workbench (NOT in PartiQL):
SELECT status,
COUNT(*) AS orders,
SUM(total) AS revenue,
AVG(total) AS avg_order,
MIN(total) AS smallest,
MAX(total) AS largest
FROM orders
GROUP BY status
ORDER BY revenue DESCItu COUNT, SUM, AVG, MIN, MAX, GROUP BY, dan ORDER BY — yang tidak
satu pun dapat dinyatakan DynamoDB atau PartiQL — dalam satu pernyataan. Ini adalah
irisan analitis yang sama dengan SQL untuk DynamoDB;
untuk cerita pengelompokan lengkap lihat
DynamoDB GROUP BY.
Workbench jujur tentang model akses di baliknya, bukan Postgres yang berpura-pura:
- Baris tetap datang melalui Query/Scan DynamoDB yang sebenarnya. Sebuah
GROUP BYatas seluruh tabel tetaplah sebuahScandi baliknya — Workbench memunculkan biaya itu alih-alih menyembunyikannya, tradeoff Query-vs-Scan yang sama. - Agregat berjalan pada atribut skalar yang dimaterialisasi setelah baris mendarat.
FAQ
Bisakah saya menghitung Item di DynamoDB tanpa men-scan?
Tidak persis. Untuk count yang persis dan terkini Anda harus membaca Item —
Select=COUNT tetap mengukur setiap Item yang dihitung. Satu-satunya opsi tanpa-scan
adalah DescribeTable.ItemCount yang perkiraan (diperbarui ~setiap 6 jam) atau
sebuah Item counter yang Anda pelihara sendiri pada setiap penulisan.
Bagaimana cara menghitung Item berdasarkan sebuah GSI?
Jalankan Query (atau Scan) terhadap index dengan Select=COUNT. Menghitung
melalui sebuah partisi GSI yang sempit jauh lebih murah daripada men-scan tabel
dasar, karena Anda hanya membaca Item di partisi index itu — modelkan index di
sekitar count yang Anda butuhkan.
Apakah DescribeTable.ItemCount akurat?
Ia perkiraan. Referensi
API
menyatakan DynamoDB memperbarui ItemCount dan TableSizeBytes "approximately every
six hours," dan "recent changes might not be reflected in this value." Jangan gunakan
di tempat yang membutuhkan angka persis atau live.
Bisakah DynamoDB melakukan SUM atau AVG?
Tidak secara native, dan tidak di PartiQL — grammar SELECT
PartiQL
tidak memiliki fungsi agregat. Agregasikan di aplikasi Anda, pelihara sebuah counter
(opsional melalui DynamoDB Streams), atau jalankan SUM/AVG di SQL Workbench
DynoTable.
Apa perbedaan antara Count dan ScannedCount?
ScannedCount adalah berapa banyak Item yang dievaluasi DynamoDB sebelum filter
Anda; Count adalah berapa banyak yang tersisa setelahnya. Keduanya sama saat tidak
ada filter expression. Celah besar di antara keduanya berarti count yang tidak
efisien.
Perlu men-sum, merata-rata, atau mengelompokkan data DynamoDB Anda tanpa menulis loop scan? Unduh DynoTable dan jalankan di sebuah Tab Workbench. Membandingkan klien terlebih dahulu? Lihat di mana posisinya dibandingkan dengan GUI DynamoDB biasa.