sql >> Base de Datos >  >> RDS >> Mysql

Sphinx vs. MySql - Buscar a través de la lista de amigos (eficiencia/velocidad)

Ok, así es como veo que esto funciona.

Tengo exactamente el mismo problema con MongoDB. MongoDB "ofrece" capacidades de búsqueda, pero al igual que MySQL, nunca debe usarlas, a menos que desee ahogarse con problemas de IO, CPU y memoria y verse obligado a usar muchos más servidores para hacer frente a su índice de lo que normalmente haría.

La idea general si usa Sphinx (u otra tecnología de búsqueda) es reducir el costo por servidor al tener un buscador de índice de alto rendimiento.

Sphinx, sin embargo, no es un motor de almacenamiento. No es tan simple consultar relaciones exactas entre tablas, han solucionado esto un poco con SphinxQL pero debido a la naturaleza del índice de texto completo, todavía no hace una unión integral como la que obtendrías en MySQL.

En cambio, almacenaría las relaciones dentro de MySQL pero tendría un índice de "usuarios" dentro de Sphinx.

En mi sitio web personalmente tengo 2 índices:

  • principal (aloja usuarios, videos, canales y listas de reproducción)
  • ayuda (búsqueda en el sistema de ayuda)

Estos se actualizan delta una vez cada minuto. Dado que los índices en tiempo real todavía son un poco experimentales a veces y personalmente he visto problemas con altas tasas de inserción/eliminación, mantengo las actualizaciones delta. Por lo tanto, usaría un índice delta para actualizar los principales objetos de búsqueda de mi sitio, ya que requiere menos recursos y tiene más rendimiento que los índices en tiempo real (de mis propias pruebas).

Tenga en cuenta que para procesar las eliminaciones y lo que no sea su colección Sphinx a través delta, necesitará una lista de eliminación y ciertos filtros para su índice delta. Aquí hay un ejemplo de mi í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
}

Esto procesa las eliminaciones y adiciones una vez por minuto, lo que es prácticamente en tiempo real para una aplicación web real.

Así que ahora sabemos cómo almacenar nuestros índices. Necesito hablar de las relaciones. Sphinx (aunque tiene SphinxQL) no hará uniones integrales entre datos, por lo que personalmente recomendaría hacer la relación fuera de Sphinx, no solo eso, sino que, como dije, esta tabla de relaciones tendrá una gran carga, por lo que esto es algo que podría afectar el Índice de esfinge.

Haría una consulta para seleccionar todas las identificaciones y usar ese conjunto de identificaciones usar el método de "filtro" en la API de sphinx para filtrar el índice principal a identificaciones de documentos específicas. Una vez hecho esto, puede buscar en Sphinx normalmente. Este es el método de mayor rendimiento que he encontrado hasta la fecha para lidiar con esto.

La clave para recordar en todo momento es que Sphinx es una tecnología de búsqueda, mientras que MySQL es una tecnología de almacenamiento. Ten eso en cuenta y deberías estar bien.

Editar

Como dijo @N.B (que pasé por alto en mi respuesta), Sphinx tiene SphinxSE. Aunque primitivo y todavía en una especie de etapa de prueba de su desarrollo (igual que los índices en tiempo real), proporciona un almacenamiento de tipo MyISAM/InnoDB real a Sphinx. esto es genial Sin embargo, hay advertencias (como con cualquier cosa):

  • El lenguaje es primitivo
  • Las uniones son primarias

Sin embargo, puede/podría hacer el trabajo que está buscando, así que asegúrese de investigarlo.