Denne forespørgsel:
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));
Er svært at optimere med kun indekser. Det bedste indeks er et, der starter med published og så har de andre kolonner -- det er ikke klart, hvad deres rækkefølge skal være. Årsagen er, at alle undtagen published bruger ikke = .
Fordi dit præstationsproblem er en slags, tyder det på, at mange rækker bliver returneret. Typisk bruges et indeks til at opfylde WHERE klausul før indekset kan bruges til ORDER BY . Det gør det svært at optimere.
Forslag . . . Ingen er så gode:
- Hvis du vil have adgang til dataene efter måned, kan du overveje at opdele dataene efter måned. Det vil gøre forespørgslen uden
ORDER BYhurtigere, men hjælper ikkeORDER BY. - Prøv forskellige rækkefølger af kolonner efter
publishedi indekset. Du finder måske den eller de mest selektive kolonner. Men igen, dette fremskynder forespørgslen før sorteringen. - Tænk på måder, hvorpå du kan strukturere forespørgslen for at have flere lighedsbetingelser i
WHEREklausul eller for at returnere et mindre sæt data. - (Virkelig ikke anbefalet) Sæt et indeks på
publishedog bestillingskolonnen. Brug derefter en underforespørgsel til at hente dataene. Sæt ulighedsbetingelserne (INog så videre) i den ydre forespørgsel. Underforespørgslen vil bruge indekset til at sortere og derefter filtrere resultaterne.
Grunden til, at det sidste ikke anbefales, er fordi SQL (og MySQL) ikke garanterer rækkefølgen af resultater fra en underforespørgsel. Men fordi MySQL materialiserer underforespørgsler, er resultaterne virkelig i orden. Jeg kan ikke lide at bruge udokumenterede bivirkninger, som kan ændre sig fra version til version.