select * from update_audit where scopeid=35 and formid=78005 and record_link_id=9897;
hur ovanstående fråga fungerar internt i cassandra?
i huvudsak kommer alla data för partition scopeid=35
och formid=78005
att returneras och filtreras sedan av record_link_id
index. Det kommer att leta efter record_link_id
posten för 9897
, och försök att matcha upp poster som matchar raderna returneras där scopeid=35
och formid=78005
. Skärningspunkten mellan raderna för partitionstangenterna och indextangenterna kommer att returneras.
hur hög kardinalitet kolumn (record_link_id)index kommer att påverka frågans prestanda för ovanstående fråga?
högkardinalitetsindex skapar i huvudsak en rad för (nästan) varje post i huvudtabellen. Prestanda påverkas, eftersom Cassandra är utformad för att utföra sekventiella läsningar för frågeresultat. En indexfråga tvingar i huvudsak Cassandra att utföra slumpmässiga läsningar. När kardinaliteten i ditt indexerade värde ökar, så tar tiden det tar att hitta det frågade värdet.
kommer cassandra att beröra alla noder för ovanstående fråga? Varför?
Nej. Det bör bara röra en nod som är ansvarig för scopeid=35
och formid=78005
partition. Index lagras också lokalt, innehåller bara poster som är giltiga för den lokala noden.
skapa index över kolumner med hög kardinalitet kommer att vara den snabbaste och bästa datamodellen
problemet här är att metoden inte skalar och kommer att vara långsam om update_audit
är en stor dataset. MVP Richard Low har en bra artikel om sekundära index(the Sweet Spot för Cassandra Secondary Indexing), och särskilt på denna punkt:
Om ditt bord var betydligt större än minnet skulle en fråga vara mycket långsam även för att returnera bara några tusen resultat. Att återvända potentiellt miljontals användare skulle vara katastrofalt trots att det verkar vara en effektiv fråga.
i praktiken betyder det att indexering är mest användbar för att returnera tiotals, kanske hundratals resultat. Tänk på detta när du nästa överväger att använda ett sekundärt index.
nu kommer din inställning att först begränsa av en specifik partition att hjälpa (eftersom din partition säkert borde passa in i minnet). Men jag känner att det bättre valet här skulle vara att göra record_link_id
en klusternyckel istället för att förlita sig på ett sekundärt index.
redigera
hur har index på lågt kardinalitetsindex när det finns miljontals användare skala även när vi tillhandahåller primärnyckeln
det beror på hur breda dina rader är. Det knepiga med extremt låga kardinalitetsindex är att % av raderna som returneras vanligtvis är större. Tänk till exempel på en bred rad users
tabell. Du begränsar med partitionsnyckeln i din fråga, men det returneras fortfarande 10 000 rader. Om ditt index är på något som gender
, måste din fråga filtrera bort ungefär hälften av dessa rader, vilket inte fungerar bra.
sekundära index tenderar att fungera bäst på (i avsaknad av en bättre beskrivning) ”mitt på vägen” kardinalitet. Med hjälp av ovanstående exempel på en bred rad users
tabell, ett index på country
eller state
bör prestera mycket bättre än ett index på gender
(förutsatt att de flesta av dessa användare inte alla bor i listan samma land eller stat).
redigera 20180913
För ditt svar på 1: A frågan ” Hur ovanstående fråga fungerar internt i cassandra?”, vet du vad som är beteendet när du frågar med pagination?
Tänk på följande diagram, taget från Java-Drivrutinsdokumentationen (v3.6):
i grund och botten kommer personsökning att göra att frågan bryts upp och återgår till klustret för nästa iteration av resultat. Det skulle vara mindre sannolikt att timeout, men prestanda kommer att trenda nedåt, proportionellt mot storleken på den totala resultatuppsättningen och antalet noder i klustret.
TL;DR; ju mer begärda resultat sprids över fler noder, desto längre tid tar det.