Use
IN BOOLEAN MODE
. O índice de data não é útil. Não há como combinar os dois índices.
Cuidado, se um usuário pesquisar algo que apareça em 30 mil linhas, a consulta será lenta. Não há nenhuma maneira direta em torno dele.
Suspeito que você tenha um
TEXT
coluna na tabela? Se sim, há esperança. Em vez de fazer cegamente SELECT *
, vamos primeiro encontrar os ids e obter o LIMIT
aplicado, então faça o *
. 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;
Junto com
PRIMARY KEY(date, id),
INDEX(id),
FULLTEXT(...)
Esta formulação e indexação deve funcionar assim:
- Usar
FULLTEXT
para encontrar 30 mil linhas, entregue o PK. - Com o PK, classifique 30 mil linhas por
date
. - Escolha os últimos 10, entregando
date, id
- Volte para a mesa 10 vezes usando o PK.
- Ordenar novamente. (Sim, isso é necessário.)
Mais (Respondendo a uma infinidade de comentários):
O objetivo por trás da minha reformulação é evitar buscar todos colunas de 30K linhas. Em vez disso, ele busca apenas a
PRIMARY KEY
, reduz para 10 e busca *
apenas 10 linhas. Muito menos coisas espalhadas. Em relação a
COUNT
em uma tabela InnoDB:- INDEX(col) faz com que um índice scan funciona para
SELECT COUNT(*)
ouSELECT COUNT(col)
sem umWHERE
. - Sem
INDEX(col),
SELECT COUNT(*)will use the "smallest" index; but
SELECT COUNT(col)` precisará de uma tabela digitalizar. - Uma verificação de tabela é geralmente mais lento que uma verificação de índice.
- Tenha cuidado com o tempo -- Isso é significativamente afetado pelo fato de o índice e/ou tabela já estar armazenado em cache na RAM.
Outra coisa sobre
FULLTEXT
é o +
na frente de palavras -- para dizer que cada palavra deve existir, senão não há correspondência. Isso pode reduzir os 30K. O
FULLTEXT
index entregará a date, id
é ordem aleatória, não ordem PK. De qualquer forma, é 'errado' assumir qualquer ordenação, portanto, é 'certo' adicionar ORDER BY
, então deixe o Optimizer lançá-lo se saber que é redundante. E às vezes o Optimizer pode tirar proveito do ORDER BY
(não no seu caso). Removendo apenas o
ORDER BY
, em muitos casos, torna uma consulta muito mais rápida. Isso ocorre porque evita buscar, digamos, 30 mil linhas e classificá-las. Em vez disso, ele simplesmente fornece "qualquer" 10 linhas. (Eu não tenho experiência com o Postgres, então não posso responder a essa pergunta.)