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

Sphinx vs. MySql - Pesquisa na lista de amigos (eficiência/velocidade)


Ok, é assim que eu vejo isso funcionando.

Eu tenho exatamente o mesmo problema com o MongoDB. O MongoDB "oferece" recursos de pesquisa, mas, assim como o MySQL, você nunca deve usá-los, a menos que queira ser sufocado com problemas de IO, CPU e memória e ser forçado a usar muito mais servidores para lidar com seu índice do que normalmente faria.

A ideia geral se usar o Sphinx (ou outra tecnologia de pesquisa) é reduzir o custo por servidor com um pesquisador de índice de alto desempenho.

Sphinx, no entanto, não é um mecanismo de armazenamento. Não é tão simples consultar relacionamentos exatos entre tabelas, eles corrigiram isso um pouco com SphinxQL, mas devido à natureza do índice de texto completo, ele ainda não faz uma junção integral como você obteria no MySQL.

Em vez disso, eu armazenaria os relacionamentos no MySQL, mas teria um índice de "usuários" no Sphinx.

No meu site eu pessoalmente tenho 2 índices:
  • principal (abriga usuários, vídeos, canais e playlists)
  • ajuda (pesquisa do sistema de ajuda)

Estes são delta atualizados uma vez a cada minuto. Como os índices em tempo real ainda são um pouco experimentais às vezes e eu pessoalmente tenho visto problemas com altas taxas de inserção/exclusão, mantenho as atualizações delta. Então, eu usaria um índice delta para atualizar os principais objetos pesquisáveis ​​do meu site, pois isso consome menos recursos e tem mais desempenho do que os índices em tempo real (dos meus próprios testes).

Observe que para processar exclusões e o que não é sua coleção Sphinx através do delta, você precisará de uma killlist e certos filtros para seu índice delta. Aqui está um exemplo do meu índice:
source main_delta : main
{
    sql_query_pre = SET NAMES utf8
    sql_query_pre =
    sql_query = \
        SELECT id, deleted,  _id, uid, listing, title, description, category, tags, author_name, duration, rating, views, type, adult, videos, UNIX_TIMESTAMP(date_uploaded) AS date_uploaded \
        FROM documents \
        WHERE id>( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 ) OR update_time >( SELECT last_index_time FROM sph_counter WHERE counter_id=1 )

    sql_query_killlist = SELECT id FROM documents WHERE update_time>=( SELECT last_index_time FROM sph_counter WHERE counter_id=1 ) OR deleted = 1
}

Isso processa exclusões e adições uma vez a cada minuto, o que é praticamente em tempo real para um aplicativo da web real.

Então agora sabemos como armazenar nossos índices. Eu preciso falar sobre os relacionamentos. Sphinx (mesmo que tenha SphinxQL) não fará junções integrais nos dados, então eu pessoalmente recomendaria fazer o relacionamento fora do Sphinx, não apenas isso, mas como eu disse, essa tabela de relacionamento terá alta carga, então isso é algo que pode afetar o Índice da esfinge.

Eu faria uma consulta para escolher todos os ids e usar esse conjunto de ids usaria o método "filter" na API sphinx para filtrar o índice principal para ids de documentos específicos. Feito isso, você pode pesquisar no Sphinx normalmente. Este é o método mais eficiente que encontrei até hoje para lidar com isso.

A principal coisa a ser lembrada em todos os momentos é que o Sphinx é uma tecnologia de pesquisa, enquanto o MySQL é uma tecnologia de armazenamento. Tenha isso em mente e você deve estar bem.

Editar


Como o @N.B disse (que eu ignorei na minha resposta), o Sphinx tem o SphinxSE. Embora primitivo e ainda em estágio de teste de seu desenvolvimento (o mesmo que índices em tempo real), ele fornece um armazenamento real do tipo MyISAM/InnoDB para o Sphinx. Isso é incrível. No entanto, há ressalvas (como com qualquer coisa):
  • A linguagem é primitiva
  • As junções são primitivas

No entanto, pode / poderia fazer o trabalho que você procura, portanto, verifique-o.