Brug IN BOOLEAN MODE
.
Datoindekset er ikke nyttigt. Der er ingen måde at kombinere de to indekser på.
Pas på, hvis en bruger søger efter noget, der dukker op i 30.000 rækker, vil forespørgslen være langsom. Der er ingen ligetil væk omkring det.
Jeg formoder, at du har en TEXT
kolonne i tabellen? Hvis det er tilfældet, er der håb. I stedet for blindt at gøre SELECT *
, lad os først finde id'erne og få LIMIT
anvendt, derefter udfør *
.
SELECT a.*
FROM tbl AS a
JOIN ( SELECT date, id
FROM tbl
WHERE MATCH(...) AGAINST (...)
ORDER BY date DESC
LIMIT 10 ) AS x
USING(date, id)
ORDER BY date DESC;
Sammen med
PRIMARY KEY(date, id),
INDEX(id),
FULLTEXT(...)
Denne formulering og indeksering skulle fungere sådan her:
- Brug
FULLTEXT
for at finde 30.000 rækker skal du levere PK. - Med PK skal du sortere 30.000 rækker efter
date
. - Vælg de sidste 10, leverer
date, id
- Ræk tilbage til bordet 10 gange ved hjælp af PK.
- Sortér igen. (Ja, det er nødvendigt.)
Mere (Svarer på et væld af kommentarer):
Målet bag min omformulering er at undgå at hente alle kolonner på 30.000 rækker. I stedet henter den kun PRIMARY KEY
, sænker det derefter til 10 og henter derefter *
kun 10 rækker. Meget mindre ting skovlet rundt.
Vedrørende COUNT
på en InnoDB-tabel:
- INDEX(col) gør det sådan, at et indeks scanningen fungerer for
SELECT COUNT(*)
ellerSELECT COUNT(col)
uden enWHERE
. - Uden
INDEX(col),
SELECT COUNT(*)will use the "smallest" index; but
SELECT COUNT(col)` skal bruge en tabel scan. - En tabelscanning er normalt langsommere end en indeksscanning.
- Vær forsigtig med timing -- Det er væsentligt påvirket af, om indekset og/eller tabellen allerede er cachelagret i RAM.
En anden ting om FULLTEXT
er +
foran ord -- at sige, at hvert ord skal eksistere, ellers er der ingen match. Dette kan skære ned på 30K.
FULLTEXT
index vil levere date, id
er tilfældig rækkefølge, ikke PK rækkefølge. Under alle omstændigheder er det 'forkert' at antage enhver bestilling, derfor er det 'rigtigt' at tilføje ORDER BY
, og lad derefter optimeringsværktøjet smide det, hvis det ved det at det er overflødigt. Og nogle gange kan Optimizer drage fordel af ORDER BY
(ikke i dit tilfælde).
Fjerner kun ORDER BY
, får i mange tilfælde en forespørgsel til at køre meget hurtigere. Dette er fordi det undgår at hente f.eks. 30K rækker og sortere dem. I stedet leverer den blot "enhver" 10 rækker.
(Jeg har ikke erfaring med Postgres, så jeg kan ikke besvare det spørgsmål.)