DynamoDB Seyrek İndeksler
seyrek endeksyalnızca kendi içeriğini taşıyan öğeleri tutan ikincil bir endekstir. temel özellik — böylece büyük bir tablonun küçük, sıcak bir alt kümesi kendine ait olur önceden filtrelenmiş, sorgulamaya hazır koleksiyon.
Milyonlarca satırınız var ama gün boyu çalıştırdığınız sorgu küçücük bir dilime dokunuyor: açık destek biletleri, ödenmemiş faturalar, incelenmek üzere işaretlenen hesaplar.
Bu dilimin filtrelenmesi yine de tüm tabloyu tarar ve her okuma için sizi faturalandırır. bir seyrek dizin bunun yerine endeksin kendisini küçük yapar.
DynamoDB'de seyrek indeks nedir?
Seyrek dizin, yalnızca anahtar niteliğini taşıyan öğeleri tutan ikincil bir dizindir. DynamoDB bu anahtarın eksik olduğu herhangi bir öğeyi atladığından, yalnızca istenen öğelerin (açık biletler, ödenmemiş faturalar) yazabileceği bir anahtar icat edersiniz ve endeks tam olarak bu alt küme haline gelir. Sorgular daha sonra sadece onu okur, filtre yoktur, okuma kapasitesi boşa gitmez.
- İkincil dizin yalnızca kendi anahtarına sahip olan öğeleri dizine ekler.Anahtarı bir öğedir ve asla dizine girmez; yer tutucu yok, boş satır yok.
- Yani sadece aranan eşyaların taşıyacağı bir anahtar icat ediyorsunuz.Bunu aldığınız eşyaların üzerine yazın sorguyu geri kalanından kaldırın. Endeks tam olarak bu alt küme haline gelir.
- Sorgu yalnızca altkümeyi okur, filtre yoktur.Boyutu küçük sıcak kümeleri izler. tablo toplamı değil, ayarlayın.
REMOVEkaldıraçtır, boşluk bırakmaz.Boş bir dize geçerli bir dizin değildir tuşu — DynamoDB ValidationException ile yazma işleminin tamamını reddeder; niteliği silin.
Sorun: filtreleme okumaları kurtarmaz
SQL'den gelince, WHERE cümlesinin işi daralttığını varsayıyorsunuz. DynamoDB'lar
FilterExpression öyle değil. Öğeler okunduktan sonraçalışır, önce değil.
Başına AWS Developer Guide, "Bir Sorgu, bir filtrenin olup olmadığına bakılmaksızın aynı miktarda okuma kapasitesi tüketir. ifadesi mevcut" - incelenen her öğe için ödeme yaparsın, ardından maç dışı deplasmanda.
Yani 5 milyon biletinizden 50'si açıksa, filtrelenmiş Query/Scan değeri okunur
Milyonlarca kişi sana o 50'yi verecek.
Bu, her "taramam neden bu kadar pahalı" konusunun arkasındaki temel silahtır; query vs. scan tam maliyet resmine sahiptir.
Seyrek bir indeks, indeksin kendisini küçük yaparak onu atlatır.
Seyrekliğin nasıl çalıştığı
İkincil dizin yalnızca gerçekten dizinin anahtarına sahip olan öğeleri dizine ekler nitelikler.
AWS docs on sparse indexes şunu açıklayın: DynamoDB bir öğeyi yalnızca o öğe olduğunda ikincil dizine yazar endeksin temel özelliklerini taşır, dolayısıyla nadiren ayarlanan bir özelliğin üzerindeki dizin kalır doğal olarak küçüktür.
Bir öğede GSI'nin bölüm anahtarını (veya sıralama anahtarını) kaçırırsanız DynamoDB bunu yapmaz indekse yazın. Yer tutucu yok, boş satır yok; öğe yok.
Bütün mesele "varsayılan olarak yokluk"tur. status özelliğini indeksleme
o every öğeyi taşır. Yalnızca istediğiniz öğeleri sağlayan bir özellik icat edin
sorgu taşıma hiç .
Daha sonra endeks tam olarak bu öğelerin temiz bir listesi haline gelir ve buna karşı Query
yalnızca bunları okur; filtre yok, kapasite kaybı yok.
Yalnızca anahtarı taşıyan öğelerin kesiştiği, dizini besleyen temel tabloyu hayal edin:
Yalnızca anahtarlı (açık) öğeler dizine çoğaltılır; kapalı eşyalar asla içine girmez.
Bu aynı anahtar şekillendirme zihniyetidir. single-table design: anahtarlar bir amaç için oluşturduğunuz araçlardır. verilerinizin aslına sadık yansımaları değil, belirli erişim düzeni.
İşlenmiş örnek: "yalnızca açık biletler"
Bir destek bileti masası alın. Temel tablo, kimliğe göre bilet almak için anahtarlanmıştır ve bir müşterinin biletlerini listelemek:
| PK | SK | attributes |
|---|---|---|
| TICKET#a91f | DETAIL | subject, body, priority, openState |
| CUSTOMER#88 | TICKET#a91f | subject, priority, openState |
Masanın ömrü boyunca çoğu bilet kapalıolur. Ancak kontrol paneli sorgusu temsilcilerinizin bütün gün vurduğu şey "önce en eskisi olmak üzere tüm açık biletleri bana gösterin" - birkaçı Milyonlarca satır arasında saklanan yüz satır.
openBucket bölüm anahtarı ve sıralama anahtarı ile tanımlayın
openedAt ve açık biletlere yalnızca openBucket yazın. Ne zaman ayarlayın
bilet oluşturulur; REMOVE bilet çözümlendiğinde.
| PK | SK | openBucket | openedAt | |
|---|---|---|---|---|
| TICKET#a91f | DETAIL | OPEN | 2026-06-23T09:14:00Z | ← open: in the index |
| TICKET#b02c | DETAIL | OPEN | 2026-06-22T16:40:00Z | ← open: in the index |
| TICKET#77de | DETAIL | (absent) | 2026-05-30T11:02:00Z | ← closed: NOT in the index |
a91f ve b02c biletleri openBucket taşıyor, yani GSI'da yaşıyorlar. Bilet
77de çözüldü ve openBucket kaldırıldı, dolayısıyla sessizce bırakıldı.
gösterge tablosu artık ucuz bir sorgu:
Query IndexName = "open-tickets-index"
KeyConditionExpression: openBucket = "OPEN"
ScanIndexForward: true # oldest first
Bu yalnızca açık biletleri okur. Biletler kapandıkça endeks kendi kendine küçülüyor. sana open popülasyonunu izler, asla toplamı değil.
Bir statik bölüm değeri ("OPEN") burada tam olarak uygundur, çünkü set aynı kalır.
küçük. Büyük bir açık kümenin parçalanmış bir bölüm anahtarına ihtiyacı olacaktır, ancak "küçük alt küme"
index tam olarak bir değerin doğru çağrı olduğu yerdir.
İşe yarayan geçiş tek bir 'dir; Bilet çözümlendiğinde öznitelik.
REMOVE yan tümcesini ve okuma tarafı için yazılan anahtar koşulunu prototipleyin.
DynamoDB Expression Builder yerine
ExpressionAttributeNames ve :val yer tutucularını kendiniz elle monte edin.
Bunu DynoTable'da yapın
Seyrek indeksin en zor kısmı onu hangi öğelerin yaptığını görmektir sessizce düşen endekse girdi.
DynoTable tablo görünümünü ikincil bir dizine geçirmenizi ve tablo görünümünü tam olarak görmenizi sağlar.
nüfuslu alt küme. Böylece çözümlenmiş bir biletin gerçekten kaldığını onaylayabilirsiniz
open-tickets-index eski bir anahtarla oyalanmak yerine.

- Anahtarı kaldırın, boş bırakmayın.Boş bir dize geçerli bir dizin anahtarı değildir —
openBucket = ""yazmak ValidationException ile başarısız olur, bu nedenle öğe hiçbir zaman onunla indekslendi. Bir öğeyi dizinden çıkarmak için niteliğiREMOVEyapmalısınız. - Dizin 'dir.GSI eşzamansız olarak güncellenir, dolayısıyla yeni çözümlenen bilet kısa süreliğine görünmeye devam edebilir — GSI okuma support eventual consistency only. "Bu bilet şu anda açık mı?" diye güvenmeyin.
- Zihin nitelikleri.Dizindeki
Queryyalnızca ona yansıtılan nitelikler. Kontrol panelinin konu ve önceliğe ihtiyacı varsa, bunları yansıtın veya temel öğenin tamamı için fazladanGetItemödeyin. - Hem GSI'ler hem de LSI'ler seyrek olabilir— kaldıraç aynıdır: endeksi atlayın Dizine eklenmesini istemediğiniz öğelere ilişkin sıralama anahtarı. GSI genellikle daha iyi uyum sağlar, yine de: tabloyu oluşturduktan sonra ekleyebilir ve ona kendi anahtar şemasını verebilirsiniz ve kapasite. GSI vs. LSI ödünleşimi bozar.
Seyrek indeksler modeldeki en eski fikirlerden biridir. Orijinal 2007 Amazon Dynamo paper Mağazayı bilinen, yüksek hacimli erişim kalıplarına ucuza hizmet verecek şekilde kurduk.
Seyrek dizin tam olarak şudur: anahtarları, ortak sorgunun hiçbir şey okumamasını sağlayacak şekilde şekillendirin ihtiyacı yok.
Gerçekte bir tane oluşturmak ve incelemek için, download DynoTable, onu doğrultun tablonuza gidin ve veri görünümünü seyrek GSI'nize çevirin — alt küme güncellemesini şu şekilde izleyin: öğeler indeks anahtarını kazanır ve kaybeder.


