Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Sphinx vs. MySql - Suche durch Freundesliste (Effizienz/Geschwindigkeit)

Ok, so sehe ich das.

Ich habe genau das gleiche Problem mit MongoDB. MongoDB "bietet" Suchfunktionen, aber genau wie MySQL sollten Sie sie niemals verwenden, es sei denn, Sie möchten mit IO-, CPU- und Speicherproblemen erstickt werden und gezwungen sein, viel mehr Server zu verwenden, um mit Ihrem Index fertig zu werden, als Sie es normalerweise tun würden.

Der Grundgedanke bei der Verwendung von Sphinx (oder einer anderen Suchtechnologie) besteht darin, die Kosten pro Server durch einen leistungsfähigen Indexsucher zu senken.

Sphinx ist jedoch keine Speicher-Engine. Es ist nicht so einfach, genaue Beziehungen zwischen Tabellen abzufragen, sie haben dies mit SphinxQL ein wenig behoben, aber aufgrund der Natur des Volltextindexes führt er immer noch keine integrale Verknüpfung durch, wie Sie es in MySQL bekommen würden.

Stattdessen würde ich die Beziehungen in MySQL speichern, aber einen Index von "Benutzern" in Sphinx haben.

In meiner Website habe ich persönlich 2 Indizes:

  • main (beherbergt Benutzer, Videos, Kanäle und Playlists)
  • help (Suche im Hilfesystem)

Diese werden einmal pro Minute per Delta aktualisiert. Da Echtzeitindizes teilweise noch etwas experimentell sind und ich persönlich Probleme mit hohen Einfüge-/Löschraten gesehen habe, bleibe ich bei Delta-Updates. Daher würde ich einen Delta-Index verwenden, um die wichtigsten durchsuchbaren Objekte meiner Website zu aktualisieren, da dies weniger ressourcenintensiv und performanter ist als Echtzeit-Indizes (aus meinen eigenen Tests).

Beachten Sie, dass Sie eine Killlist und bestimmte Filter für Ihren Delta-Index benötigen, um Löschungen und andere Daten aus Ihrer Sphinx-Sammlung zu verarbeiten. Hier ist ein Beispiel aus meinem Index:

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
}

Dies verarbeitet Löschungen und Hinzufügungen einmal pro Minute, was für eine echte Web-App ziemlich in Echtzeit ist.

Jetzt wissen wir also, wie wir unsere Indizes speichern. Ich muss über die Beziehungen sprechen. Sphinx (obwohl es über SphinxQL verfügt) führt keine integralen Joins über Daten hinweg aus, daher würde ich persönlich empfehlen, die Beziehung außerhalb von Sphinx durchzuführen, nicht nur das, sondern wie gesagt, diese Beziehungstabelle wird stark belastet, sodass dies etwas sein könnte Auswirkungen auf die Sphinx-Index.

Ich würde eine Abfrage durchführen, um alle IDs herauszusuchen, und unter Verwendung dieses Satzes von IDs die "Filter" -Methode in der Sphinx-API verwenden, um den Hauptindex nach bestimmten Dokument-IDs zu filtern. Sobald dies erledigt ist, können Sie wie gewohnt in Sphinx suchen. Dies ist die leistungsfähigste Methode, die ich bisher gefunden habe, um damit umzugehen.

Das Wichtigste, woran man sich immer erinnern sollte, ist, dass Sphinx eine Suchtechnologie ist, während MySQL eine Speichertechnologie ist. Denken Sie daran und Sie sollten in Ordnung sein.

Bearbeiten

Wie @NB sagte (was ich in meiner Antwort übersehen habe), hat Sphinx SphinxSE. Obwohl ursprünglich und immer noch in einer Art Testphase seiner Entwicklung (genau wie Echtzeit-Indizes), bietet es Sphinx einen tatsächlichen Speicher vom Typ MyISAM/InnoDB. Das ist fantastisch. Es gibt jedoch Vorbehalte (wie bei allem):

  • Die Sprache ist ursprünglich
  • Die Verknüpfungen sind primitive

Wie auch immer, es kann/könnte die Aufgabe erfüllen, nach der Sie suchen, also schauen Sie es sich unbedingt an.