Użyj IN BOOLEAN MODE .
Indeks dat nie jest przydatny. Nie ma możliwości połączenia tych dwóch indeksów.
Uważaj, jeśli użytkownik szuka czegoś, co pojawia się w 30 tys. wierszach, zapytanie będzie powolne. Nie ma prostoty wokół tego.
Podejrzewam, że masz TEXT kolumna w tabeli? Jeśli tak, to jest nadzieja. Zamiast ślepo wykonywać SELECT * , najpierw znajdźmy identyfikatory i zdobądźmy LIMIT zastosowano, wtedy wykonaj * .
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;
Razem z
PRIMARY KEY(date, id),
INDEX(id),
FULLTEXT(...)
To sformułowanie i indeksowanie powinny działać w następujący sposób:
- Użyj
FULLTEXTaby znaleźć 30 tys. wierszy, dostarcz PK. - Za pomocą PK posortuj 30 tys. wierszy według
date. - Wybierz ostatnie 10, dostarczając
date, id - Sięgnij z powrotem do stołu 10 razy, używając PK.
- Posortuj ponownie. (Tak, to jest konieczne).
Więcej (Odpowiada na mnóstwo komentarzy):
Celem mojego przeformułowania jest uniknięcie pobierania wszystkich kolumny 30 tys. wydziwianie. Zamiast tego pobiera tylko PRIMARY KEY , następnie zmniejsza to do 10, a następnie pobiera * tylko 10 rzędów. Dużo mniej rzeczy porozrzucanych.
Dotyczy COUNT w tabeli InnoDB:
- INDEX(col) sprawia, że indeks skanowanie działa dla
SELECT COUNT(*)lubSELECT COUNT(col)bezWHERE. - Bez
INDEX(col),SELECT COUNT(*)will use the "smallest" index; butSELECT COUNT(col)` będzie wymagać tabeli skanowanie. - Skanowanie tabeli jest zazwyczaj wolniej niż skanowanie indeksu.
- Uważaj na synchronizację – znacząco wpływa na to, czy indeks i/lub tabela są już buforowane w pamięci RAM.
Kolejna rzecz o FULLTEXT to + przed słowami - aby powiedzieć, że każde słowo musi istnieć, w przeciwnym razie nie ma dopasowania. Może to obniżyć 30K.
FULLTEXT index dostarczy date, id to kolejność losowa, a nie kolejność PK. W każdym razie „błędem” jest przyjmowanie dowolnej kolejności, stąd „właściwe” jest dodanie ORDER BY , a następnie pozwól Optymalizatorowi go wyrzucić, jeśli wie że jest zbędny. A czasami Optymalizator może skorzystać z ORDER BY (nie w twoim przypadku).
Usunięcie tylko ORDER BY , w wielu przypadkach znacznie przyspiesza działanie zapytania. Dzieje się tak, ponieważ pozwala uniknąć pobierania, powiedzmy, 30 tys. wierszy i ich sortowania. Zamiast tego po prostu dostarcza „dowolnych” 10 wierszy.
(Nie mam doświadczenia z Postgresem, więc nie mogę odpowiedzieć na to pytanie).