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
FULLTEXT
aby 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; but
SELECT 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).