Was es mit ALLOW FILTERING auf sich hat
Werfen Sie einen Blick auf unsere Cassandra-Indexing-Seite und erfahren Sie, wie Sie das „ALLOW FILTERING“-Problem mit Storage-attached-Indizes (SAI) umgehen können. Außerdem erwartet Sie eine praktische Übung.
Auf dem London C* Summit stellte ich fest, dass meinen Gesprächspartnern nicht immer klar war, warum Cassandra für manche CQL-Abfragen ALLOW FILTERING erfordert und für andere nicht.
Warum ist manchmal ALLOW FILTERING erforderlich?
Sehen wir uns zum Beispiel die folgende Tabelle an:
- 1
- 2
- 3
- 4
- 5
- 6
CREATE TABLE blogs (blogId int, time1 int, time2 int, author text, content text, PRIMARY KEY(blogId, time1, time2));
Nehmen wir an, Sie führen die folgende Abfrage aus:
SELECT * FROM blogs;
In diesem Fall zeigt Cassandra alle Daten an, die in den Tabelleneinträgen enthalten sind. Wenn Sie nur die Daten zu einer spezifischen Zeit (time1) möchten, fügen Sie natürlich eine entsprechende Bedingung in der Spalte time1 hinzu.
SELECT * FROM blogs WHERE time1 = 1418306451235;
Als Antwort erscheint folgende Fehlermeldung:
<em>Bad Request: Cannot execute this query as it might involve data filtering and thus may have unpredictable performance. If you want to execute this query despite the performance unpredictability, use ALLOW FILTERING.</em>
Cassandra weiß, dass die Abfrage womöglich nicht auf effiziente Weise ausgeführt werden kann. Cassandra warnt Sie deshalb: „Achtung. Eine derartige Ausführung dieser Abfrage ist womöglich keine gute Idee, da sie einen großen Teil Ihrer Rechenressourcen verbrauchen könnte.“
Die einzige Weise, wie Cassandra diese Abfrage ausführen kann, besteht darin, alle Zeilen aus den Tabelleneinträgen abzufragen und dann jene herauszufiltern, die nicht den gewünschten Wert für die Spalte time1 enthalten.
Wenn Ihre Tabelle zum Beispiel eine Million Zeilen enthält und 95 Prozent davon den gewünschten Wert für die Spalte time1 haben, ist die Abfrage trotzdem relativ effizient und Sie sollten ALLOW FILTERING nutzen.
Wenn Ihre Tabelle hingegen eine Million Zeilen enthält und nur zwei Zeilen den gewünschten Wert für die time1-Spalte haben, ist Ihre Abfrage extrem ineffizient. Cassandra würde 999.998 Zeilen umsonst laden. Wird die Abfrage oft verwendet, ist es wahrscheinlich besser, einen Index zur Spalte time1 hinzuzufügen.
Unglücklicherweise hat Cassandra keine Möglichkeit, zwischen den beiden oben beschriebenen Fällen zu unterscheiden, da sie von der Datendistribution der Tabelle abhängen. Cassandra warnt Sie daher und überlässt es Ihnen, eine passende Entscheidung zu treffen.
Sekundäre Indizes und ALLOW FILTERING
Nehmen wir an, wir fügen einen Index zur Autorenspalte hinzu und führen die folgende Abfrage aus:
SELECT * FROM blogs WHERE author = ‘Jonathan Ellis’;
Cassandra zeigt hier alle Einträge an, die von Jonathan verfasst wurden, und fordert nicht ALLOW FILTERING an. Das rührt daher, dass Cassandra den sekundären Index in der Autorenspalte nutzen kann, um die entsprechenden Zeilen zu finden, und keine Filter nötig sind.
Aber nehmen wir an, dass wir die folgende Abfrage durchführen:
SELECT * FROM blogs WHERE author=’Jonathan Ellis’ and time2 = 1418306451235;
Hier fragt Cassandra ALLOW FILTERING an, da zuerst die Zeilen gefunden und geladen werden müssen, die Jonathan als Autor enthalten, und anschließend jene Zeilen herausgefiltert werden, die keine time2-Spalte entsprechend dem spezifizierten Wert enthalten.
Durch Hinzufügen eines Index zur Spalte time2 könnte sich die Abfrageperformance verbessern. Cassandra nutzt dann den Index mit der höchsten Selektivität, um die Zeilen zu finden, die geladen werden müssen. Allerdings wird ALLOW FILTERING trotzdem erforderlich sein, da die geladenen Zeilen immer noch mittels der verbleibenden Prädikate gefiltert werden müssen.
Die richtige Wahl treffen
Wenn Ihre Abfrage von Cassandra abgelehnt wird, weil eine Filterung erforderlich ist, sollten Sie dem Impuls widerstehen, einfach nur ALLOW FILTERING hinzuzufügen. Sie sollten sich Ihre Daten und Ihr Modell ansehen und darüber nachdenken, was Sie erreichen möchten. Sie haben immer mehrere Optionen.
Sie können etwa Ihr Datenmodell verändern, einen Index hinzufügen, eine weitere Tabelle verwenden oder ALLOW FILTERING nutzen.
Es ist wichtig, dass Sie die richtige Wahl für Ihren spezifischen Anwendungsfall treffen.