21

Nie jestem niezdecydowany, czy lepiej, pod względem wydajności, używać bardzo wspólnej wartości kolumny (jak Country) jako klucza partycji dla złożonego klucza podstawowego lub raczej unikalnej wartości kolumny (jak Last_Name).Cassandra: wybieranie klucza partycji

Patrząc na Cassandra 1.2's documentation about indexes uzyskać to:

"Kiedy używać indeks. Cassandra wbudowanego w indeksach są najlepsze na stole posiadające wiele wierszy, które zawierają wartości indeksowanej Więcej unikalne wartości , które istnieją w konkretnej kolumnie, tym więcej wydatków na zapytania i utrzymanie indeksu . mają średnio na zapytanie i utrzymanie indeksu. Załóżmy na przykład, że masz tabelę użytkowników z miliardem użytkowników i chcesz wyglądać na użytkowników do stanu, w którym przebywali. Wielu użytkowników będzie korzystać z tej samej wartości kolumny dla stanu (np. CA, NY, TX itd.). Byłby to dobry kandydat do indeksu na .

Kiedy nie używać indeksu: Nie używać indeksu kwerendy ogromną ilość płyt za niewielką liczbę wyników. Na przykład, jeśli utworzysz indeks na kolumnie , która ma wiele różnych wartości, zapytanie między polami będzie wymagało wielu innych wyników dla bardzo niewielu wyników. W tabeli z miliardem użytkowników, wyszukiwanie użytkowników według ich adresu e-mail (wartość, która zazwyczaj jest unikalna dla każdego użytkownika) zamiast ich stanu, prawdopodobnie będzie bardzo niewydajna: . Prawdopodobnie bardziej wydajne byłoby ręczne utrzymywanie tabeli jako formy indeksu zamiast korzystania z wbudowanego indeksu Cassandra . W przypadku kolumn zawierających unikalne dane, czasem jest to fine performance-mądry, aby używać indeksu dla wygody, tak długo, jak objętość zapytanie do tabeli posiadające kolumny indeksowanej jest umiarkowana i nie pod stałym obciążeniem.”

Looking at the examples from CQL's SELECT dla

Zapytania złożone klucze podstawowe i sortowania wyników”, widzę coś takiego jak UUID używany jako klucz partycji ... które wskazywałyby, że lepiej jest użyć czegoś raczej unikalny?

enter image description here

Odpowiedz

39

Indeksowanie w zapisanej dokumentacji odnosi się do indeksów wtórnych. W kassandra jest difference between the primary and secondary indexes. W przypadku indeksu wtórnego byłoby naprawdę źle mieć bardzo unikalne wartości, jednak w przypadku komponentów klucza podstawowego zależy to od tego, na którym elemencie się koncentrujemy. W kluczu podstawowym mamy te składniki:

PRIMARY KEY (klucz partycjonowania, grupowanie key_1 ... grupowanie key_n)

Klucz partycjonowania jest używane do dystrybucji danych w różnych węzłach, a jeśli chcesz, aby twoje węzły były zbalansowane (tj. dobrze rozłożone dane w każdym węźle), a następnie chcesz, aby twój klucz partycjonowania był jak najbardziej losowy.Właśnie dlatego w przykładzie wykorzystano identyfikatory UUID.

Klucz klastrowania jest używany jako do zamawiania, dzięki czemu kwerenda na kolumny z określonym kluczem klastrowania może być bardziej wydajna. Właśnie tam chcesz, aby twoje wartości nie były unikalne i tam, gdzie wystąpiłoby trafienie wydajności, gdyby były rzadkie unikalne wiersze.

The cql docs mają dobre wyjaśnienie tego, co się dzieje.

+0

Czy to znaczy, „Klucz podziału” jest jeden wiersz, a „grupowanie key_1” i tak dalej, czy wartość zamawiania wewnątrz tym samym wierszu? Dzięki za odpowiedź, to jest odpowiedź wylądowałem po długim poszukiwaniu korelacji między partycjonowania, klucz podziału i związku klucz podstawowy. Z tego co widzę, to jest klucz podziału że bałagan podziału między klastra, a jeżeli jest to przypadkowe, reszta kluczowych składników, tj Klastry key_1 i tak dalej, klucze klastrowania nie wpływają dystrybucji pomiędzy węzłami . –

+2

@RavindranathAkila Klucz klastrowania wpływa na sposób wyrównania kolumn (uporządkowanych) w węźle fizycznym, ale masz rację, że dystrybucja między węzłami zależy wyłącznie od klucza partycjonowania. –

+0

Dzięki Lyuben! To bardzo pomaga! –

8

jeśli używasz cql3, zważywszy rodziny kolumna:

CREATE TABLE table1 (
    a1 text, 
    a2 text, 
    b1 text, 
    b2 text, 
    c1 text, 
    c2 text, 
    PRIMARY KEY ((a1, a2), b1, b2)) 
); 

definiując klucz podstawowy ((A1, A2, ...), B1, B2, ...)

oznacza to, że:

a1, a2, ... są stosowane do jednostek pola klucza wiersza w celu:

  • określić, w jaki sposób dane są partycje
  • określić, co jest phisically przechowywane w jednym rzędzie
  • określane jako rzędzie klucz lub partycji klucz

b1, b2, ... są kolumny pola rodzin używane do klastra klucza wiersza w celu:

  • tworzyć zestawy logicznych w pojedynczym rzędzie
  • umożliwić bardziej elastyczne systemy wyszukiwania, takich jak zakres zakres
  • określane jako kolumny klucza lub CLUS ter klucz

Wszystkie pozostałe pola są skutecznie multipleksowane/duplikowane dla każdej możliwej kombinacji kluczy kolumn. Poniżej znajduje się przykład dotyczący kluczy złożonych z kluczami partycji i kluczy klastrowych.

Jeśli chcesz używać zapytań o zakres, możesz użyć indeksów pomocniczych lub (zaczynając od cql3), możesz zadeklarować te pola jako klucze klastra. Pod względem szybkości posiadania ich jako klucza skupienia tworzy pojedynczy szeroki rząd. To ma wpływ na szybkość, ponieważ będzie pobierać wielokrotność klastrów kluczowych wartości, takie jak:

select * from accounts where Country>'Italy' and Country<'Spain'

+0

Zastanawiam się o wydajności przy użyciu kluczy klastrowych i zapytań o zakres. Dokumentacja jest dość głośna, jeśli chodzi o używanie tylko drugich indeksów do porównywania równości, ponieważ porównania zakresów będą miały Cassandrę powtarzającą się po wynikach do porównania (z powodu indeksowania KEYS). Jak wiesz o zapytaniach dotyczących odległości przy użyciu kluczy klastrowych (tj. Podstawowych części klucza, które nie składają się na klucz wiersza/partycji)? – DanielSmedegaardBuus

+2

Wtórne indeksy efektywnie tworzą drzewo binarne z kluczami wiersza skrótu podzielonymi przez wybraną kolumnę. Podczas gdy klucze kolumn są przeznaczone do indeksowania kolumn w rzędzie. Wskaźniki średnie powinny być stosowane tylko wtedy, gdy moc zbioru wartości w kolumnie jest niska (np krajach lub kodów pocztowych) – natbusa

+0

klucz podstawowy ((A1), B1, B2)) jest taki sam jak klucz podstawowy (A1, B1, B2) – natbusa

1

Jestem pewien, że masz odpowiedź, ale nadal może to pomóc w lepszym zrozumieniu.

CREATE TABLE table1 (
    a1 text, 
    a2 text, 
    b1 text, 
    b2 text, 
    c1 text, 
    c2 text, 
    PRIMARY KEY ((a1, a2), b1, b2)) 
); 

Tutaj klucze partycji to (a1, a2), a klawisze wiersza to b1, b2.

połączenie obu kluczy partycji i kluczy wierszy musi być unikalne dla każdego nowego rekordu.

powyższy klucz podstawowy może być zdefiniowany w ten sposób.

Node< key, value> 

Node<(a1a2), Map< b1b2, otherColumnValues>> 

jak wiemy Partition Key jest odpowiedzialna za dystrybucję danych po drugiej stronie węzłach.

Więc jeśli wstawiasz 100 rekordów w tabela1 z samych kluczy działowych i różnych kluczy wierszy. będzie przechowywać dane w tym samym węźle, ale w różnych kolumnach.

logicznie możemy reprezentować tak.

Node<(a1a2), Map< string1, otherColumnValues>, Map< string2, otherColumnValues> .... Map< string100, otherColumnValues>> 

Dzięki temu rekord będzie zapisywany sekwencyjnie w pamięci.