Pesquisa de texto completo com InnoDB

93

Estou desenvolvendo um aplicativo da web de alto volume, em que parte dele é um banco de dados MySQL de postagens de discussão que precisará crescer para mais de 20 milhões de linhas, sem problemas.

Eu estava planejando originalmente usar MyISAM para as tabelas (para os recursos de busca de texto completo embutidos ), mas o pensamento de toda a tabela sendo bloqueada devido a uma única operação de gravação me deixa louco. Os bloqueios de nível de linha fazem muito mais sentido (sem mencionar as outras vantagens de velocidade do InnoDB ao lidar com tabelas enormes). Portanto, por esse motivo, estou bastante determinado a usar o InnoDB.

O problema é ... O InnoDB não possui recursos integrados de pesquisa de texto completo.

Devo usar um sistema de pesquisa de terceiros? Gosta do Lucene (c ++) / Sphinx ? Algum de vocês ninjas do banco de dados tem alguma sugestão / orientação?Zoie do LinkedIn (baseada em Lucene) parece ser a melhor opção no momento... tendo sido construído em torno de recursos em tempo real (o que é muito crítico para minha aplicação). Estou um pouco hesitante em me comprometer ainda sem algum insight ...

(Para sua informação: estará no EC2 com rigs de alta memória, usando PHP para servir ao front-end)

Brianreavis
fonte

Respostas:

50

Posso garantir que o texto completo do MyISAM é uma opção ruim - mesmo deixando de lado os vários problemas com as tabelas do MyISAM em geral, vi o texto completo sair dos trilhos e começar a se corromper e travar o MySQL regularmente.

Um mecanismo de pesquisa dedicado definitivamente será a opção mais flexível aqui - armazene os dados de postagem no MySQL / innodb e, em seguida, exporte o texto para o seu mecanismo de pesquisa. Você pode configurar uma compilação / publicação periódica de índice completo com bastante facilidade e adicionar atualizações de índice em tempo real se sentir a necessidade e quiser gastar o tempo.

Lucene e Sphinx são boas opções, assim como Xapian , que é bom e leve. Se você seguir o caminho do Lucene, não presuma que o Clucene será melhor, mesmo que você prefira não lutar contra o Java, embora eu não esteja realmente qualificado para discutir os prós e os contras de ambos.

Ian Wilkes
fonte
7
Solr (baseado no Lucene) pode escalar enormemente e é muito poderoso e flexível. Empregamos o Solr (especificamente a edição LucidWorks for Solr) e posso dizer que foi uma grande vitória. O Sphinx também tem uma promessa séria, mas, em última análise, sua falta de tipos de dados pode ser problemática, pelo menos para nossa aplicação. O Sphinx é muito rápido e se for adequado às suas necessidades também é uma escolha sólida.
Cody Caughlan,
Muito obrigado vocês dois; ótimas respostas. Estive folheando os documentos do Solr e parece uma ótima solução. Vejo que também alimenta alguns sites enormes. Acho que Solr é o bilhete. Obrigado rapazes. Além disso, é bom saber de suas dores de cabeça com o MyISAM, Ian ... será bom tê-las em mente no futuro. Em outros projetos, evitarei tentar usar o recurso de texto completo.
brianreavis
11
Estava se perguntando o que fez Ian dizer "não presuma que Clucene vai melhorar"? como membro da equipe principal do clucene, posso não ser tão objetivo, mas para mim parece que a porta C ++ otimizada de qualquer biblioteca Java aumentará seu desempenho até o teto. Eu recomendaria a ninguém que postasse esses comentários sem ter pelo menos uma olhada no produto que eles estão desonrando.
synhershko
4
Quando você bate MyISAM, você realmente precisa ser mais específico. "Fora dos trilhos" é muito vago, e pode ter sido devido a um único bug na compilação que você estava usando, possivelmente já corrigido.
bobobobo
6
Mas e se você não tiver a opção de instalar o software no servidor - quais alternativas existem neste caso?
acme
56

Junto com a eliminação geral do MyISAM, o InnoDB full-text search (FTS) está finalmente disponível no MySQL versão 5.6.4.

Muitos detalhes interessantes em https://dev.mysql.com/doc/refman/5.6/en/innodb-fulltext-index.html .

Enquanto outros motores têm muitos recursos diferentes, este é InnoDB, então é nativo (o que significa que há um caminho de atualização), e isso o torna uma opção válida.

Jeremy Smyth
fonte
1
O link do artigo é 403 proibido
Marco Demaio
11

Você deve gastar uma hora e fazer a instalação e o test-drive do Sphinx e Lucene. Veja se algum deles atende às suas necessidades, no que diz respeito a atualizações de dados.

Uma das coisas que me decepcionou no Sphinx é que ele não suporta muito bem inserções incrementais. Ou seja, é muito caro reindexar após uma inserção, tão caro que a solução recomendada é dividir seus dados em linhas mais antigas e imutáveis ​​e em linhas mais novas e voláteis. Portanto, cada pesquisa que seu aplicativo faz teria que pesquisar duas vezes: uma vez no índice maior para linhas antigas e também no índice menor para linhas recentes. Se isso não se integrar com seus padrões de uso, este Sphinx não é uma boa solução (pelo menos não em sua implementação atual).

Eu gostaria de apontar outra solução possível que você pode considerar: Pesquisa personalizada do Google . Se você pode aplicar algum SEO ao seu aplicativo da web, terceirize a função de indexação e pesquisa para o Google e incorpore um campo de texto de pesquisa do Google em seu site. Pode ser a maneira mais econômica e escalonável de tornar seu site pesquisável.

Bill Karwin
fonte
Obrigado, Bill. Sim, a documentação do Sphinx me fez vacilar um pouco sobre como ele lida com as atualizações de índice. É bom ter confirmado. Esse tipo de sistema provavelmente se transformaria em um pesadelo para mim, eu imagino. Quanto à Pesquisa personalizada do Google, essa é uma opção. No entanto, meu principal problema com isso é apenas o índice não em tempo real e a falta de personalização. Definir o estilo dos resultados e obter dados adicionais será crucial para mim. Obrigado por participar --- as informações da Esfinge são certamente boas de saber!
brianreavis
3

Talvez você não deva descartar o FT do MySQL tão rapidamente. Craigslist costumava usá-lo .

A velocidade do MySQL e a pesquisa de texto completo permitiram que o craigslist atendesse seus usuários. O craigslist usa o MySQL para atender aproximadamente 50 milhões de pesquisas por mês a uma taxa de até 60 pesquisas por segundo. "

editar

Conforme comentado abaixo, o Craigslist parece ter mudado para o Sphinx em algum momento no início de 2009.

bobobobo
fonte
O artigo que eu
vinculei
O PDF do estudo de caso parece ser de 2004, época em que havia 50 milhões de pesquisas por mês. A página Sphinx indica 50 milhões de pesquisas por dia , o que provavelmente explica a razão pela qual eles mudaram para uma solução de pesquisa dedicada.
Halil Özgür
1

Sphinx, como você observou, é muito bom para essas coisas. Todo o trabalho está no arquivo de configuração. Certifique-se de que qualquer tabela com as strings tenha alguma chave de ID de número inteiro exclusivo e você deve ficar bem.

Gregg Lind
fonte
0

tente isso

ROUND((LENGTH(text) - LENGTH(REPLACE(text, 'serchtext', ''))) / LENGTH('serchtext'),0)!=0
Rakesh Ojha
fonte
0

Você deveria dar uma olhada no Sphinx. Vale a pena tentar. Sua indexação é super rápida e é distribuída. Você deve dar uma olhada neste webminar (http://www.percona.com/webinars/2012-08-22-full-text-search-throwdown). Ele fala sobre pesquisa e tem alguns benchmarks interessantes. Você pode achar isso útil.

Maomé
fonte
0

Se tudo mais falhar, sempre há soundex_match , que infelizmente não é muito rápido e preciso

user1612250
fonte
0

Para qualquer pessoa presa em uma versão anterior do MySQL / MariaDB (ou seja, usuários do CentOS) onde o InnoDB não suporta pesquisas de texto completo, minha solução ao usar tabelas InnoDB foi criar uma tabela MyISAM separada para o que eu queria pesquisar.

Por exemplo, minha tabela InnoDB principal estava productscom várias chaves e integridade referencial. Em seguida, criei uma tabela MyISAM simples chamada product_searchcontendo dois campos, product_ide product_nameonde o último foi definido como um FULLTEXTíndice. Ambos os campos são efetivamente uma cópia do que está na producttabela principal .

Em seguida, procuro na tabela MyISAM usando texto completo e faço uma junção interna de volta à tabela InnoDB.

O conteúdo da tabela MyISAM pode ser mantido atualizado por meio de gatilhos ou do modelo do aplicativo.

Eu não recomendaria isso se você tiver várias tabelas que exigem texto completo, mas para uma única tabela, parece uma solução adequada até que você possa atualizar.

MrCarrot
fonte