Dokumentacja Cassandra stwierdza,
Nie używaj indeksu w następujących sytuacjach:
- W kolumnach o wysokiej liczności, ponieważ następnie przeszukujesz ogromną liczbę rekordów w celu uzyskania niewielkiej liczby wyników. Zobacz problemy przy użyciu indeksu kolumny o wysokiej liczności poniżej.
To idzie,
Jeśli utworzysz indeks w kolumnie o wysokiej liczności, która ma wiele różnych wartości, zapytanie między polami spowoduje wiele prób uzyskania bardzo niewielu wyników. W tabeli z miliardem piosenek wyszukiwanie piosenek według pisarza (wartość, która jest zwykle unikalna dla każdej piosenki) zamiast według ich wykonawcy, może być bardzo nieefektywne. Prawdopodobnie bardziej efektywne byłoby ręczne utrzymywanie tabeli jako formy indeksu zamiast korzystania z wbudowanego indeksu Cassandra. W przypadku kolumn zawierających unikalne dane czasami wygodniej jest używać indeksu dla wygody, o ile wolumin zapytania do tabeli mającej indeksowaną kolumnę jest umiarkowany i nie jest pod stałym obciążeniem.
Ale tak naprawdę nigdy nie odpowiada na pytanie: dlaczego jest nieefektywne? Nie mam pojęcia, co oznacza „ręczne utrzymywanie tabeli jako formy indeksu”. Ale w pewnym sensie jest to sprzeczne z „… czasem wygodnym jest użycie indeksu dla wygody, o ile objętość zapytania jest umiarkowana…”
Czy to po prostu próbuje mi powiedzieć, żebym używał PK, kiedy i gdzie mogę? Jaka jest nieefektywność? Rozumiem, że zapytanie, które trafiłoby do indeksu, musiałoby wykonać zapytanie do każdego węzła w klastrze, a następnie każdy węzeł przeprowadziłby wyszukiwanie w swoim lokalnym indeksie, a wyniki zostałyby następnie zagregowane. To niekoniecznie jest drogie (każde wyszukiwanie indeksu powinno być dość tanie), z wyjątkiem tego, że płacimy za opóźnienie w sieci, ponieważ musimy czekać na najwolniejszy węzeł partii. Czy coś tu brakuje?
Ale jeśli mam kolekcję zawierającą bajillion przedmiotów, które - w rzadkich przypadkach - muszą zostać wyszukane za pomocą innego, ale prawie unikalnego atrybutu… jest to właściwe zastosowanie, prawda?
¹Każdy? IDK, jeśli replikacja oznacza, że może to trafić 1/3 klastra dla współczynnika replikacji 3, czy nie?
Trochę terminologii: Tabela nadrzędna to tabela, na której tworzony jest indeks. Pomocnicza tabela indeksowa to tabela utworzona w celu utrzymania indeksu w innej tabeli.
Dane wtórnej tabeli indeksu są przechowywane w tym samym węźle, co dane tabeli nadrzędnej. Partycjoner Cassandra nie dzieli i nie dystrybuuje danych tabeli indeksów. Jeśli więc chcesz przeprowadzić wyszukiwanie w kolumnie indeksu, wszystkie węzły są pytane, a nie tylko węzły repliki zawierające dane. (węzeł koordynujący nie wie, gdzie znajdują się dane) https://www.datastax.com/dev/blog/cassandra-native-secondary-index-deep-dive
W przypadku kolumn o dużej liczności, takich jak ssn lub jakiś inny unikalny identyfikator, będzie mapowanie jeden do jednego z kluczem podstawowym. Jeśli utworzysz indeks w takiej kolumnie, dane rezydują na liczbie węzłów współczynnika replikacji, ale wywołanie wyszukiwania jest wykonywane na wszystkich węzłach. W najlepszym przypadku koordynator trafia bezpośrednio w węzły zawierające dane, a po osiągnięciu poziomu spójności otrzymujesz wynik. Co gorsza, jeśli dane, których szukasz, nie są obecne w indeksie, czekasz, aż wszystkie węzły odpowiedzą, że nie ma danych. Tak więc dla każdego wywołania wtórnej tabeli indeksu trafiają wszystkie węzły. Porównaj to z liczbą trafień tylko węzła replikacji dla każdego wywołania odnośnika, na wypadek gdyby tabela była normalną tabelą C *.
źródło