Problemet her var som jeg beskrev i opdatering 2 af mit spørgsmål. MySQL bruger indekser til hurtigt at udføre ORDER BY-operationer. Mere specifikt bruger MySQL B-træer til at indeksere kolonner (såsom tidsstempler - p.time/r.time), som bruger lidt mere plads, men giver mulighed for hurtigere sortering.
Problemet med min forespørgsel var, at den sorterede efter tidskolonnen i to tabeller ved at bruge tidsstemplet fra repost-tabellen, hvis den var tilgængelig, og post-tabellen ellers. Da MySQL ikke kan kombinere B-træerne fra begge tabeller, kan den ikke udføre hurtig indekssortering på kolonner fra to forskellige tabeller.
Jeg ændrede min forespørgsel og tabelstruktur på to måder for at løse dette.
1) Udfør først filtrering baseret på blokerede brugere, så bestilling skal kun foretages på indlæg, der er tilgængelige for den aktuelle bruger. Dette var ikke roden til problemet, men er praktisk optimering. f.eks.
SELECT * FROM (SELECT * FROM Post p WHERE p.author_id NOT IN (4, 5, 6...))...
2) Behandl hvert indlæg som et genindlæg af dets forfatter, så hvert indlæg er garanteret at have et genindlæg og repost.time, som kan indekseres og sorteres på. f.eks.
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
I slutningen af dagen kom problemet ned til BESTIL EFTER - denne tilgang reducerede forespørgselstiden fra ca. 8 sekunder til 20 ms.