Ich habe eine INNODB-Tabelle levels
:
+ -------------------- + -------------- + ------ + ----- + --------- + ------- + | Feld | Geben Sie | ein Null | Schlüssel | Standard | Extra | + -------------------- + -------------- + ------ + ----- + --------- + ------- + | id | int (9) | NEIN | PRI | NULL | | | Levelname | varchar (20) | NEIN | | NULL | | | user_id | int (10) | NEIN | | NULL | | | Benutzername | varchar (45) | NEIN | | NULL | | | Bewertung | dezimal (5,4) | NEIN | | 0,0000 | | | Stimmen | int (5) | NEIN | | 0 | | | spielt | int (5) | NEIN | | 0 | | | date_published | Datum | NEIN | MUL | NULL | | | user_comment | varchar (255) | NEIN | | NULL | | | spielbarer_Zeichen | int (2) | NEIN | | 1 | | | is_featured | tinyint (1) | NEIN | MUL | 0 | | + -------------------- + -------------- + ------ + ----- + --------- + ------- +
Es gibt ~ 4 Millionen Zeilen. Aufgrund der Front-End-Funktionalität muss ich diese Tabelle mit einer Vielzahl von Filtern und Sortierungen abfragen. Sie sind auf playable_character
, rating
, plays
, und date_published
. Sie date_published
können nach dem letzten Tag, der letzten Woche, dem letzten Monat oder jederzeit (in den letzten 3 Jahren) gefiltert werden. Es gibt auch Paging. Abhängig von den Benutzeroptionen können die Abfragen beispielsweise wie folgt aussehen:
SELECT * FROM levels
WHERE playable_character = 0 AND
date_published BETWEEN date_sub(now(), INTERVAL 3 YEAR) AND now()
ORDER BY date_published DESC
LIMIT 0, 1000;
SELECT * FROM levels
WHERE playable_character = 4 AND
date_published BETWEEN date_sub(now(), INTERVAL 1 WEEK) AND now()
ORDER BY rating DESC
LIMIT 4000, 1000;
SELECT * FROM levels
WHERE playable_character = 5 AND
date_published BETWEEN date_sub(now(), INTERVAL 1 MONTH) AND now()
ORDER BY plays DESC
LIMIT 1000, 1000;
Ich sollte das hinzufügen rating
und werde plays
immer als abgefragt DESC
. Nur date_published
kann entweder DESC
oder sein ASC
.
Ich habe mit einem Index begonnen idx_date_char(date_published, playable_character)
, der bei der ersten Beispielabfrage hier hervorragend funktioniert hat. Basierend auf einigen anderen Antworten habe ich zu zwei anderen Indizes gewechselt (date_published, playable_character, play) und (date_published, playable_character, Bewertung).
Die erste Abfrage wird immer noch sehr schnell ausgeführt. In EXPLAIN passieren jedoch einige ungewöhnliche Dinge, wenn player_character = x eine bestimmte Anzahl von Zeilen (~ 700.000) überschreitet: In EXPLAIN wird USING WHERE angezeigt.
Die erste Frage ist also, ob Verbesserungen an der Abfrage oder den Indizes möglich sind, und zweitens, welche MySQL-Einstellungen geändert werden sollten, um die großen Ergebnismengen zu berücksichtigen.
Anregungen sehr geschätzt. TIA.