Mysql
 sql >> Datenbank >  >> RDS >> Mysql

mysql - Optimierung von ORDER BY COALESCE für verbundene Tabellenspalten

Das Problem hier war, wie ich in Update 2 meiner Frage beschrieben habe. MySQL verwendet Indizes, um ORDER BY-Operationen schnell auszuführen. Genauer gesagt verwendet MySQL B-trees um Spalten zu indizieren (z. B. Zeitstempel - p.time/r.time), die etwas mehr Platz verbrauchen, aber eine schnellere Sortierung ermöglichen.

Das Problem mit meiner Abfrage war, dass sie in zwei Tabellen nach der Zeitspalte sortierte, wobei der Zeitstempel aus der Repost-Tabelle, falls verfügbar, und ansonsten die Post-Tabelle verwendet wurde. Da MySQL die B-Bäume aus beiden Tabellen nicht kombinieren kann, kann es keine schnelle Indexsortierung für Spalten aus zwei verschiedenen Tabellen durchführen.

Ich habe meine Abfrage- und Tabellenstruktur auf zwei Arten geändert, um dies zu lösen.

1) Führen Sie zuerst eine Filterung basierend auf blockierten Benutzern durch, sodass die Bestellung nur für Beiträge erfolgen muss, auf die der aktuelle Benutzer zugreifen kann. Dies war nicht die Wurzel des Problems, sondern ist eine praktische Optimierung. zB

SELECT * FROM (SELECT * FROM Post p WHERE p.author_id NOT IN (4, 5, 6...))...

2) Behandeln Sie jeden Beitrag als Repost seines Autors, sodass jeder Beitrag garantiert einen verknüpfbaren Repost und eine repost.time zum Indexieren und Sortieren hat. zB

SELECT * FROM (...) LEFT JOIN p.reposts repost ON (p.id = repost.post_id AND 
repost.time = (
  SELECT MIN(r.time) FROM Repost r WHERE p.id = r.post_id
  AND r.user_id IN (1, 2, 3...) AND r.user_id NOT IN (4, 5, 6...))
))
WHERE (repost.id IS NOT NULL) ORDER BY repost.time DESC LIMIT 0, 10

Am Ende des Tages lief das Problem auf ORDER BY hinaus - dieser Ansatz reduzierte die Abfragezeit von etwa 8 Sekunden auf 20 ms.