Mysql
 sql >> Database >  >> RDS >> Mysql

Sphinx vs. MySql - Cerca nell'elenco degli amici (efficienza/velocità)

Ok, ecco come lo vedo funzionare.

Ho lo stesso identico problema con MongoDB. MongoDB "offre" capacità di ricerca ma, proprio come MySQL, non dovresti mai usarle a meno che tu non voglia essere soffocato da problemi di I/O, CPU e memoria ed essere costretto a utilizzare molti più server per far fronte al tuo indice di quanto faresti normalmente.

L'idea generale se si utilizza Sphinx (o un'altra tecnologia di ricerca) è ridurre il costo per server grazie a un ricercatore di indici efficiente.

Sphinx tuttavia non è un motore di archiviazione. Non è così semplice interrogare le relazioni esatte tra le tabelle, hanno rimediato un po' con SphinxQL ma, a causa della natura dell'indice di testo completo, non esegue ancora un join integrale come si otterrebbe in MySQL.

Invece memorizzerei le relazioni all'interno di MySQL ma avrei un indice di "utenti" all'interno di Sphinx.

Nel mio sito ho personalmente 2 indici:

  • principale (ospita utenti, video, canali e playlist)
  • aiuto (ricerca nel sistema di aiuto)

Questi sono aggiornati delta una volta al minuto. Poiché gli indici in tempo reale sono ancora un po' sperimentali a volte e personalmente ho riscontrato problemi con alti tassi di inserimento/cancellazione, mi tengo agli aggiornamenti delta. Quindi userei un indice delta per aggiornare i principali oggetti ricercabili del mio sito poiché questo è meno dispendioso in termini di risorse e più performante degli indici in tempo reale (dai miei test).

Nota per elaborare le eliminazioni e ciò che non è la tua raccolta Sphinx tramite delta avrai bisogno di una killlist e di alcuni filtri per il tuo indice delta. Ecco un esempio dal mio indice:

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
}

Questo elabora le eliminazioni e le aggiunte una volta al minuto, il che è praticamente in tempo reale per una vera app Web.

Quindi ora sappiamo come archiviare i nostri indici. Ho bisogno di parlare delle relazioni. Sphinx (anche se ha SphinxQL) non eseguirà join integrali tra i dati, quindi consiglierei personalmente di fare la relazione al di fuori di Sphinx, non solo, ma come ho detto questa tabella delle relazioni riceverà un carico elevato, quindi questo è qualcosa che potrebbe influire sul Indice della Sfinge.

Farei una query per selezionare tutti gli ID e utilizzare quel set di ID utilizzando il metodo "filtro" sull'API sphinx per filtrare l'indice principale fino a ID documento specifici. Una volta fatto, puoi cercare in Sphinx normalmente. Questo è il metodo più efficace che ho trovato fino ad oggi per affrontare questo problema.

La cosa fondamentale da ricordare in ogni momento è che Sphinx è una tecnologia di ricerca mentre MySQL è una tecnologia di archiviazione. Tienilo a mente e dovresti essere a posto.

Modifica

Come ha detto @NB (che ho trascurato nella mia risposta) Sphinx ha SphinxSE. Sebbene sia primordiale e ancora in una sorta di fase di test del suo sviluppo (come gli indici in tempo reale), fornisce a Sphinx un vero e proprio archivio di tipo MyISAM/InnoDB. Questo è bellissimo. Tuttavia ci sono delle avvertenze (come per qualsiasi cosa):

  • La lingua è primitiva
  • I join sono primativi

Tuttavia può/potrebbe fare il lavoro che stai cercando, quindi assicurati di esaminarlo.