Použijte IN BOOLEAN MODE
.
Index data není užitečný. Neexistuje způsob, jak tyto dva indexy zkombinovat.
Pozor, pokud uživatel hledá něco, co se zobrazuje ve 30 000 řádcích, dotaz bude pomalý. Není to přímočaré.
Mám podezření, že máte TEXT
sloupec v tabulce? Pokud ano, existuje naděje. Místo slepého provádění SELECT *
, pojďme nejprve najít ID a získat LIMIT
použito, pak proveďte *
.
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;
Společně s
PRIMARY KEY(date, id),
INDEX(id),
FULLTEXT(...)
Tato formulace a indexování by mělo fungovat takto:
- Použijte
FULLTEXT
chcete-li najít 30 000 řádků, doručte PK. - Pomocí PK seřaďte 30 tisíc řádků podle
date
. - Vyberte posledních 10 s dodáním
date, id
- Sáhněte zpět do tabulky 10krát pomocí PK.
- Znovu seřadit. (Ano, je to nutné.)
Další (Reakce na množství komentářů):
Cílem mého přeformulování je vyhnout se načítání všech sloupců 30 tis. řádky. Místo toho načte pouze PRIMARY KEY
, pak to zmenší na 10 a poté načte *
pouze 10 řádků. Mnohem méně věcí házených kolem.
O COUNT
na tabulce InnoDB:
- INDEX(sloupec) z něj dělá index skenování funguje pro
SELECT COUNT(*)
neboSELECT COUNT(col)
bezWHERE
. - Bez
INDEX(col),
SELECT COUNT(*)will use the "smallest" index; but
SELECT COUNT(col)` bude potřebovat tabulku skenovat. - Prohledávání tabulky je obvykle pomalejší než indexové skenování.
- Pozor na načasování – Je výrazně ovlivněno tím, zda je index nebo tabulka již uložena v paměti RAM.
Další věc o FULLTEXT
je +
před slovy -- říci, že každé slovo musí existovat, jinak neexistuje žádná shoda. To může snížit 30 000.
FULLTEXT
index doručí date, id
je náhodné pořadí, nikoli pořadí PK. Každopádně je „špatné“ předpokládat jakékoli uspořádání, proto je „správné“ přidat ORDER BY
, a pokud to ví, nechejte jej hodit Optimalizátorem že je to nadbytečné. A někdy může Optimalizátor využít výhody ORDER BY
(ne ve vašem případě).
Odstranění pouze ORDER BY
, v mnoha případech umožňuje běh dotazu mnohem rychleji. Je to proto, že se vyhne načítání řekněme 30 tisíc řádků a jejich řazení. Místo toho jednoduše dodá „jakýchkoli“ 10 řádků.
(Nemám zkušenosti s Postgres, takže nemohu odpovědět na tuto otázku.)