Използвайте IN BOOLEAN MODE .
Индексът на датите не е полезен. Няма начин да комбинирате двата индекса.
Внимавайте, ако потребител търси нещо, което се показва в 30K реда, заявката ще бъде бавна. Няма директен път около него.
Подозирам, че имате TEXT колона в таблицата? Ако е така, има надежда. Вместо сляпо да правите SELECT * , нека първо намерим идентификаторите и да получим LIMIT приложен, след това направете * .
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;
Заедно с
PRIMARY KEY(date, id),
INDEX(id),
FULLTEXT(...)
Тази формулировка и индексиране трябва да работят по следния начин:
- Използвайте
FULLTEXTза да намерите 30K реда, доставете PK. - С PK сортирайте 30K реда по
date. - Изберете последните 10, доставяйки
date, id - Върнете се в масата 10 пъти с помощта на ПК.
- Сортирайте отново. (Да, това е необходимо.)
Още (В отговор на множество коментари):
Целта зад моето преформулиране е да избегна изтеглянето на всички колони от 30K редове. Вместо това той извлича само PRIMARY KEY , след това намалява това до 10, след което извлича * само 10 реда. Много по-малко неща се изсипват наоколо.
Относно COUNT на таблица на InnoDB:
- INDEX(col) прави така, че индекс сканирането работи за
SELECT COUNT(*)илиSELECT COUNT(col)безWHERE. - Без
INDEX(col),SELECT COUNT(*)will use the "smallest" index; butSELECT COUNT(col)` ще се нуждае от таблица сканиране. - Сканирането на таблица е обикновено по-бавно от индексно сканиране.
- Внимавайте с времето – То се влияе значително от това дали индексът и/или таблицата вече са кеширани в RAM.
Още нещо за FULLTEXT е + пред думи -- да се каже, че всяка дума трябва да съществува, иначе няма съвпадение. Това може да намали 30K.
FULLTEXT index ще предостави date, id е произволен ред, а не PK ред. Както и да е, е „грешно“ да се приема каквато и да е подредба, следователно е „правилно“ да добавите ORDER BY , след което оставете оптимизатора да го хвърли, ако знае че е излишен. И понякога оптимизаторът може да се възползва от ORDER BY (не във вашия случай).
Премахване само на ORDER BY , в много случаи кара заявката да се изпълнява много по-бързо. Това е така, защото избягва извличането, да речем, 30K реда и сортирането им. Вместо това той просто предоставя "всеки" 10 реда.
(Нямам опит с Postgres, така че не мога да отговоря на този въпрос.)