Menengah6 menit baca

Proyeksi indeks DynamoDB

Saat Anda membuat secondary index, DynamoDB tidak secara otomatis menyalin seluruh item ke dalamnya. Anda memilih apa yang disalin — proyeksi indeks. Pilih terlalu sedikit dan query Anda membayar baca kedua untuk mengambil sisanya; pilih semuanya dan Anda membayar storage serta biaya tulis ekstra pada setiap update. Itu trade-off yang Anda set sekali saat pembuatan indeks dan hidup dengannya.

(Jangan bingungkan ini dengan projection expression, yang memangkas atribut yang dikembalikan satu baca. Halaman ini tentang apa yang disimpan indeks secara fisik — lihat projection expressions untuk yang lain.)

Apa itu proyeksi indeks DynamoDB?

Proyeksi adalah himpunan atribut yang DynamoDB salin dari tabel dasar ke secondary index. Anda pilih salah satu dari tiga tipe: KEYS_ONLY (hanya key), INCLUDE (key plus daftar atribut bernama), atau ALL (seluruh item). Lebih banyak proyeksi berarti lebih sedikit fetch tabel dasar tetapi storage dan biaya tulis lebih tinggi.

  • Proyeksi adalah himpunan atribut yang disalin ke secondary index.
  • KEYS_ONLY — hanya key tabel dan indeks. Terkecil, termurah.
  • INCLUDE — key plus daftar atribut ekstra yang Anda pilih.
  • ALL — setiap atribut item. Terbesar; query tidak pernah butuh tabel dasar.
  • Atribut yang tidak diproyeksikan sekadar tidak tersedia dari GSI — app Anda harus mengeluarkan baca tabel dasar sendiri. (Hanya LSI yang mengambil atribut non-projected untuk Anda, dengan biaya baca ekstra.)
  • Lebih banyak proyeksi = lebih banyak storage + lebih banyak biaya tulis, karena setiap write tabel dasar menyebar ke indeks.

Masalahnya: indeks yang membuat Anda baca dua kali

Katakan Anda menjalankan support desk dengan GSI yang membiarkan Anda mendaftar tiket open by priority. Anda project KEYS_ONLY agar tetap ramping. Query kembali cepat — tetapi hanya memberi ID tiket, dan layar antrian butuh subject, assignee, dan age tiap tiket.

Jadi sekarang kode Anda melakukan putaran baca kedua terhadap tabel dasar untuk menghidrasi setiap hasil. "Satu query" yang Anda desain sebenarnya query plus N get, dan latensi serta biaya yang Anda coba hemat langsung kembali. Proyeksi terlalu tipis untuk access pattern.

Apa yang disalin tiap tipe proyeksi

Item dasar: keys + subject +assignee + age + bodyKEYS_ONLY: hanya keysINCLUDE: keys + subject,assignee, ageALL: setiap atribut
  • KEYS_ONLY menyimpan hanya key tabel dasar dan key indeks. Pakai saat query hanya perlu tahu item mana yang cocok dan Anda akan fetch detail di tempat lain — atau tidak sama sekali.
  • INCLUDE menyimpan key plus daftar tetap atribut yang Anda namai. Sweet spot: project tepat field yang dibutuhkan query untuk render, dan tidak lebih.
  • ALL menyalin seluruh item. Query sepenuhnya self-served dari indeks, dengan biaya menduplikasi seluruh storage dan write throughput item ke dalamnya.

Untuk antrian support desk, INCLUDE dengan subject, assignee, dan age adalah pilihan yang tepat — antrian merender dari indeks saja, tanpa fetch kedua dan tanpa menduplikasi body tiket yang besar ke indeks.

Biaya yang Anda tukar

Setiap atribut yang Anda project disimpan kedua kali dan ditulis ulang di indeks setiap kali item dasar berubah. Jadi proyeksi ALL yang dermawan pada tabel yang sering di-update mengalikan storage dan kapasitas tulis. Project apa yang dibaca query, bukan "semuanya, jaga-jaga."

Satu subtilitas yang perlu diketahui: dengan indeks sparse, proyeksi tetap hanya menampung item yang membawa key indeks — jadi INCLUDE/ALL pada sparse index tetap kecil karena indeksnya sendiri kecil. Timbang pengali storage dan tulis untuk proyeksi Anda dengan kalkulator harga DynamoDB, dan susun query indeks sendiri dengan pembuat ekspresi DynamoDB.

Melihat proyeksi di DynoTable

DynoTable mendaftar tiap secondary index tabel dan membiarkan Anda Query langsung melaluinya. Jalankan access pattern yang sama terhadap tabel dasar dan terhadap GSI dan bandingkan hasilnya — atribut yang hilang dari hasil indeks tepat yang tidak diproyeksikannya, jadi efek proyeksi terlihat tanpa membaca ulang definisi tabel.

Memilih indeks DynamoDB mana yang dijalankan query, di index picker DynoTable.
Memilih indeks DynamoDB mana yang dijalankan query, di index picker DynoTable.

Jebakan + langkah selanjutnya

  • Atribut non-projected pada GSI berarti fetch tabel dasar — desain proyeksi di sekitar apa yang dirender query.
  • ALL jarang gratis — ia menduplikasi storage dan biaya tulis; default ke INCLUDE kecuali indeks benar-benar butuh setiap field.
  • Proyeksi sebagian besar tetap. Anda tidak bisa bebas mengedit proyeksi GSI nanti tanpa membuat ulang indeks — pilih dengan sengaja di depan.
  • Terkait: GSI vs LSI dan sparse indexes membentuk seberapa banyak proyeksi benar-benar disimpan.

Ingin melihat apa yang sebenarnya dikembalikan tiap indeks sebelum Anda mendesain ulang? Unduh DynoTable dan Query tabel Anda langsung.

Biaya hidrasi: KEYS_ONLY + N get

Kembali ke contoh antrian support desk: 50 tiket open ditampilkan dengan subject, assignee, dan age.

ProyeksiQuery indeksBaca lanjutanSketsa EC RCU (item dasar 2 KB)
KEYS_ONLY50 key dikembalikan50 × GetItem~50 RCU indeks + ~50 RCU dasar
INCLUDE subject, assignee, age50 baris mandiritidak ada~50 RCU indeks saja
ALL50 salinan penuhtidak ada~50 RCU indeks; storage + write amp lebih tinggi

Angka exact bergantung pada ukuran atribut yang diproyeksikan — tempel sampel tiket ke kalkulator ukuran item dan kalikan dengan kedalaman antrian. INCLUDE yang hanya mendaftar field UI sering mengalahkan ALL saat atribut body besar dan jarang ditampilkan di list view.

Perilaku fetch proyeksi LSI

Hanya LSI yang bisa opsional mengambil atribut non-projected dari tabel dasar selama query (dengan biaya baca tambahan). GSI tidak pernah — atribut yang hilang mengharuskan aplikasi Anda memanggil GetItem pada tabel dasar. Perbedaan itu mendorong banyak desain GSI ke proyeksi INCLUDE yang sedikit lebih lebar di depan.

Mengubah proyeksi nanti

Proyeksi GSI tetap saat pembuatan. Memperlebar KEYS_ONLY ke INCLUDE memerlukan membuat indeks baru, backfill, mengalihkan traffic, dan menghapus indeks lama — rencanakan field sebelum launch. LSI berbagi keterbatasan yang sama.

Saat mengevaluasi access pattern baru, Query indeks kandidat di DynoTable dan daftar atribut mana yang muncul — celah memetakan 1:1 ke entri proyeksi yang hilang.

Pasangkan dengan sparse index

GSI sparse yang hanya mengindeks tiket status = open menyimpan proyeksi hanya untuk baris open. INCLUDE pada indeks itu tetap murah bahkan saat tabel dasar menampung jutaan tiket closed — indeks tidak pernah menyalinnya.

Gabungkan dengan pattern sparse index saat subset yang difilter kecil relatif terhadap tabel.

Bangun access pattern dulu

Pakai query builder untuk memprototype query GSI — key condition, projection expression, dan filter — sebelum Anda mengubah CloudFormation. Tukar tipe proyeksi di diskusi desain dengan bertanya kolom mana yang dirender UI; sisanya tetap di tabel dasar.

Diperbarui