Използвайте 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; but
SELECT COUNT(col)` ще се нуждае от таблица сканиране. - Сканирането на таблица е обикновено по-бавно от индексно сканиране.
- Внимавайте с времето – То се влияе значително от това дали индексът и/или таблицата вече са кеширани в RAM.
Още нещо за FULLTEXT
е +
пред думи -- да се каже, че всяка дума трябва да съществува, иначе няма съвпадение. Това може да намали 30K.
FULLTEXT
index ще предостави date, id
е произволен ред, а не PK ред. Както и да е, е „грешно“ да се приема каквато и да е подредба, следователно е „правилно“ да добавите ORDER BY
, след което оставете оптимизатора да го хвърли, ако знае че е излишен. И понякога оптимизаторът може да се възползва от ORDER BY
(не във вашия случай).
Премахване само на ORDER BY
, в много случаи кара заявката да се изпълнява много по-бързо. Това е така, защото избягва извличането, да речем, 30K реда и сортирането им. Вместо това той просто предоставя "всеки" 10 реда.
(Нямам опит с Postgres, така че не мога да отговоря на този въпрос.)