Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

MySQL:índice composto fulltext + btree?


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:
  1. Usar FULLTEXT para encontrar 30 mil linhas, entregue o PK.
  2. Com o PK, classifique 30 mil linhas por date .
  3. Escolha os últimos 10, entregando date, id
  4. Volte para a mesa 10 vezes usando o PK.
  5. 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(*) ou SELECT COUNT(col) sem um WHERE .
  • 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.)