Hier ist ein weiteres Datenbankproblem, auf das ich gestoßen bin.
Ich habe eine nach Datumsbereichen partitionierte Myisam-Nachschlagetabelle mit 200 Millionen Datensätzen und ~ 150 Spalten. In dieser Tabelle muss ich kaskadierende SELECT-Anweisungen ausführen, um die Daten zu filtern. Ausgabe:
Filter 126M
Filter 110M
Filter 40M
Filter 5M
Filter 100k
Jedes einzelne SELECT ist sehr komplex mit Regex (= kein Index möglich) und mehreren Vergleichen, weshalb ich möchte, dass sie die geringstmögliche Anzahl von Zeilen abfragen.
Es gibt ungefähr 500 einzigartige Filter und ungefähr 200 ständige Benutzer. Jeder Filter muss für jeden Benutzer ausgeführt werden, insgesamt ca. 100.000 Kombinationen.
Große Frage: Gibt es eine Möglichkeit für jede nachfolgende SELECT-Anweisung, nur die vorherige Teilmenge abzufragen?
Beispiel: Filter 5 sollte nur die 5 Millionen Zeilen von Abfrage 4 abfragen müssen, um diese 100.000 Ergebnisse zu erhalten. Momentan müssen alle 200 Millionen Datensätze durchsucht werden.
BEARBEITEN aktueller Ansatz: Cache-Tabelle
CREATE TABLE IF NOT EXISTS cache
( filter_id int(11) NOT NULL,
user_id int(11) NOT NULL,
lookup_id int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
ALTER TABLE cache ADD PRIMARY KEY (filter_id,user_id);
Dies würde die Beziehung zwischen einzelnen Datenzeilen aus der Nachschlagetabelle und den Filtern enthalten. Außerdem kann ich den Primärindex verwenden, um alle lookup_ids aus dem vorherigen Filter abzurufen.
Abfrage für nachfolgende Filter:
SELECT SUM( column), COUNT(*)
FROM cache c
LEFT JOIN lookup_table l
ON c.lookup_id= l.id
WHERE c.filter_id = 1
AND c. user_id= x
AND l.regex_column = preg_rlike...
Antworten:
0 für die Antwort № 1Vielleicht sollten Sie den Primärschlüssel ausgewählter Datensätze in einer Art temporärer Tabelle speichern? Verbinden Sie im nächsten Schritt diese temporäre Tabelle mit Ihrer Haupttabelle.