Gebruik IN BOOLEAN MODE
.
De datumindex is niet nuttig. Er is geen manier om de twee indexen te combineren.
Pas op, als een gebruiker zoekt naar iets dat wordt weergegeven in 30K-rijen, zal de zoekopdracht traag zijn. Er is geen eenvoudige manier omheen.
Ik vermoed dat je een TEXT
. hebt kolom in de tabel? Als dat zo is, is er hoop. In plaats van blindelings SELECT *
te doen , laten we eerst de id's zoeken en de LIMIT
. ophalen toegepast, dan doe de *
.
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;
Samen met
PRIMARY KEY(date, id),
INDEX(id),
FULLTEXT(...)
Deze formulering en indexering zouden als volgt moeten werken:
- Gebruik
FULLTEXT
om 30K rijen te vinden, lever de PK. - Met de PK sorteert u 30K rijen op
date
. - Kies de laatste 10 en lever
date, id
- Reik 10 keer terug in de tafel met de PK.
- Sorteer opnieuw. (Ja, dit is nodig.)
Meer (Als reactie op een overvloed aan opmerkingen):
Het doel achter mijn herformulering is om te voorkomen dat ik alles ophaal kolommen van 30K rijen. In plaats daarvan haalt het alleen de PRIMARY KEY
. op , verkleint dat vervolgens tot 10 en haalt vervolgens *
. op slechts 10 rijen. Veel minder spullen schuiven.
Over COUNT
op een InnoDB-tafel:
- INDEX(col) zorgt ervoor dat een index scan werkt voor
SELECT COUNT(*)
ofSELECT COUNT(col)
zonder eenWHERE
. - Zonder
INDEX(col),
SELECT COUNT(*)will use the "smallest" index; but
SELECT COUNT(col)` heeft een tabel nodig scannen. - Een tabelscan is meestal langzamer dan een indexscan.
- Wees voorzichtig met timing -- Het wordt aanzienlijk beïnvloed door de vraag of de index en/of tabel al in het RAM-geheugen is opgeslagen.
Nog iets over FULLTEXT
is de +
voor woorden -- om te zeggen dat elk woord moet bestaan, anders is er geen overeenkomst. Dit kan de 30K verminderen.
De FULLTEXT
index levert de date, id
is willekeurige volgorde, niet PK-volgorde. Hoe dan ook, het is 'fout' om een bestelling aan te nemen, daarom is het 'goed' om ORDER BY
toe te voegen en laat de Optimizer het dan weggooien als het weet dat het overbodig is. En soms kan de Optimizer profiteren van de ORDER BY
(niet in jouw geval).
Alleen de ORDER BY
. verwijderen zorgt er in veel gevallen voor dat een query veel sneller wordt uitgevoerd. Dit komt omdat het voorkomt dat bijvoorbeeld 30K rijen worden opgehaald en gesorteerd. In plaats daarvan levert het gewoon "elke" 10 rijen.
(Ik heb geen ervaring met Postgres, dus ik kan die vraag niet beantwoorden.)