Deze vraag:
SELECT *
FROM listings
WHERE (publishedon BETWEEN 1441105258 AND 1443614458) AND
(published = 1) AND
(cat_id in (1,2,3,4,5)) AND
(source_id in (1,2,3,4,5));
Is moeilijk te optimaliseren met alleen indexen. De beste index is er een die begint met published
en dan de andere kolommen -- het is niet duidelijk wat hun volgorde zou moeten zijn. De reden is dat alles behalve published
gebruiken niet =
.
Omdat uw prestatieprobleem op een sortering ligt, suggereert dit dat er veel rijen worden geretourneerd. Meestal wordt een index gebruikt om te voldoen aan de WHERE
clausule voordat de index kan worden gebruikt voor de ORDER BY
. Dat maakt dit moeilijk te optimaliseren.
Suggesties. . . Geen enkele is zo geweldig:
- Als u de gegevens per maand wilt openen, kunt u overwegen de gegevens per maand te partitioneren. Dat maakt de zoekopdracht zonder de
ORDER BY
sneller, maar helpt niet bij deORDER BY
. - Probeer verschillende volgorden van kolommen na
published
in de index. Misschien vindt u de meest selectieve kolom(men). Maar nogmaals, dit versnelt de zoekopdracht vóór het sorteren. - Denk na over manieren waarop u de query kunt structureren om meer gelijkheidsvoorwaarden te hebben in de
WHERE
clausule of om een kleinere set gegevens te retourneren. - (Niet echt aanbevolen) Zet een index op
published
en de bestelkolom. Gebruik vervolgens een subquery om de gegevens op te halen. Zet de ongelijkheidsvoorwaarden (IN
enzovoort) in de buitenste query. De subquery gebruikt de index om te sorteren en filtert vervolgens de resultaten.
De reden dat het laatste niet wordt aanbevolen, is omdat SQL (en MySQL) de volgorde van de resultaten van een subquery niet garanderen. Omdat MySQL echter subquery's materialiseert, zijn de resultaten echt in orde. Ik gebruik niet graag ongedocumenteerde bijwerkingen, die van versie tot versie kunnen veranderen.