select * from update_audit where scopeid=35 and formid=78005 and record_link_id=9897;
Wie funktioniert die obige Abfrage intern in Cassandra?
Im Wesentlichen werden alle Daten für die Partition scopeid=35
und formid=78005
zurückgegeben und dann nach dem record_link_id
Index gefiltert. Es wird nach dem record_link_id
Eintrag für 9897
gesucht und versucht, Einträge zu finden, die mit den zurückgegebenen Zeilen übereinstimmen, wobei scopeid=35
und formid=78005
. Der Schnittpunkt der Zeilen für die Partitionsschlüssel und die Indexschlüssel wird zurückgegeben.
Wie wirkt sich der Index der Spalte mit hoher Kardinalität (record_link_id) auf die Abfrageleistung für die obige Abfrage aus?
Indizes mit hoher Kardinalität erstellen im Wesentlichen eine Zeile für (fast) jeden Eintrag in der Haupttabelle. Die Leistung wird beeinträchtigt, da Cassandra für sequentielle Lesevorgänge für Abfrageergebnisse ausgelegt ist. Eine Indexabfrage zwingt Cassandra im Wesentlichen dazu, zufällige Lesevorgänge durchzuführen. Mit zunehmender Kardinalität Ihres indizierten Werts nimmt auch die Zeit zu, die zum Auffinden des abgefragten Werts benötigt wird.
Berührt Cassandra alle Knoten für die obige Abfrage? Warum?
Nein. Es sollte nur einen Knoten berühren, der für die scopeid=35
und formid=78005
Partition verantwortlich ist. Indizes, die lokal gespeichert werden, enthalten nur Einträge, die für den lokalen Knoten gültig sind.
Das Erstellen eines Index über Spalten mit hoher Kardinalität ist das schnellste und beste Datenmodell
Das Problem hierbei ist, dass der Ansatz nicht skaliert und langsam ist, wenn update_audit
ein großer Datensatz ist. MVP Richard Low hat einen großartigen Artikel über Sekundärindizes (den Sweet Spot für Cassandra Secondary Indexing) und insbesondere zu diesem Punkt:
Wenn Ihre Tabelle deutlich größer als der Arbeitsspeicher wäre, wäre eine Abfrage sehr langsam, selbst wenn nur wenige tausend Ergebnisse zurückgegeben würden. Die Rückgabe von potenziell Millionen von Benutzern wäre katastrophal, obwohl dies eine effiziente Abfrage zu sein scheint.In der Praxis bedeutet dies, dass die Indizierung am nützlichsten ist, um Dutzende, vielleicht Hunderte von Ergebnissen zurückzugeben. Beachten Sie dies, wenn Sie das nächste Mal einen Sekundärindex verwenden möchten.
Jetzt hilft Ihr Ansatz, zuerst durch eine bestimmte Partition einzuschränken (da Ihre Partition sicherlich in den Speicher passen sollte). Aber ich denke, die bessere Wahl wäre hier, record_link_id
zu einem Clustering-Schlüssel zu machen, anstatt sich auf einen sekundären Index zu verlassen.
Bearbeiten
Wie skaliert ein Index mit niedrigem Kardinalitätsindex, wenn Millionen von Benutzern vorhanden sind, selbst wenn wir den Primärschlüssel bereitstellen
Es hängt davon ab, wie breit Ihre Zeilen sind. Das Schwierige an extrem niedrigen Kardinalitätsindizes ist, dass der Prozentsatz der zurückgegebenen Zeilen normalerweise größer ist. Betrachten Sie beispielsweise eine users
-Tabelle mit breiter Zeile. Sie beschränken sich durch den Partitionsschlüssel in Ihrer Abfrage, aber es werden immer noch 10.000 Zeilen zurückgegeben. Wenn sich Ihr Index auf etwas wie gender
, muss Ihre Abfrage etwa die Hälfte dieser Zeilen herausfiltern, was nicht gut funktioniert.
Sekundäre Indizes funktionieren am besten (mangels einer besseren Beschreibung) „mitten auf der Straße“ Kardinalität. Unter Verwendung des obigen Beispiels einer users
-Tabelle mit breiter Zeile sollte ein Index für country
oder state
eine viel bessere Leistung erbringen als ein Index für gender
(vorausgesetzt, die meisten dieser Benutzer leben nicht alle im selben Land oder Bundesstaat).
Edit 20180913
Für Ihre Antwort auf die 1. Frage „Wie funktioniert die obige Abfrage intern in Cassandra?“, wissen Sie, was ist das Verhalten bei der Abfrage mit Paginierung?
Betrachten Sie das folgende Diagramm aus der Java-Treiberdokumentation (v3.6):
Grundsätzlich führt das Paging dazu, dass sich die Abfrage auflöst und für die nächste Iteration der Ergebnisse zum Cluster zurückkehrt. Es wäre weniger wahrscheinlich, dass es zu einem Timeout kommt, aber die Leistung wird proportional zur Größe der Gesamtergebnismenge und der Anzahl der Knoten im Cluster nach unten tendieren.
TL; DR; Je mehr angeforderte Ergebnisse über mehr Knoten verteilt sind, desto länger dauert es.