Ok, c'est comme ça que je vois cela fonctionner.
J'ai exactement le même problème avec MongoDB. MongoDB "offre" des capacités de recherche, mais tout comme MySQL, vous ne devriez jamais les utiliser à moins que vous ne vouliez être étouffé par des problèmes d'E/S, de CPU et de mémoire et être obligé d'utiliser beaucoup plus de serveurs pour faire face à votre index que vous ne le feriez normalement.
L'idée générale si vous utilisez Sphinx (ou une autre technologie de recherche) est de réduire le coût par serveur en ayant un moteur de recherche d'index performant.
Sphinx n'est cependant pas un moteur de stockage. Il n'est pas aussi simple d'interroger les relations exactes entre les tables, ils ont un peu remédié à cela avec SphinxQL mais en raison de la nature de l'index de texte intégral, il ne fait toujours pas de jointure intégrale comme vous le feriez dans MySQL.
Au lieu de cela, je stockerais les relations dans MySQL, mais j'aurais un index des "utilisateurs" dans Sphinx.
Sur mon site, j'ai personnellement 2 index :
- principal (héberge les utilisateurs, les vidéos, les chaînes et les playlists)
- help (recherche du système d'aide)
Ceux-ci sont mis à jour delta une fois par minute. Étant donné que les index en temps réel sont parfois encore un peu expérimentaux et que j'ai personnellement rencontré des problèmes avec des taux d'insertion/suppression élevés, je m'en tiens aux mises à jour delta. J'utiliserais donc un index delta pour mettre à jour les principaux objets interrogeables de mon site car cela nécessite moins de ressources et est plus performant que les index en temps réel (d'après mes propres tests).
Notez que pour traiter les suppressions et ce qui n'est pas votre collection Sphinx via delta, vous aurez besoin d'une killlist et de certains filtres pour votre index delta. Voici un exemple tiré de mon 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
}
Cela traite les suppressions et les ajouts une fois par minute, ce qui est quasiment en temps réel pour une vraie application Web.
Alors maintenant, nous savons comment stocker nos index. Je dois parler des relations. Sphinx (même s'il a SphinxQL) ne fera pas de jointures intégrales entre les données, donc je recommanderais personnellement de faire la relation en dehors de Sphinx, non seulement cela, mais comme je l'ai dit, cette table de relations obtiendra une charge élevée, c'est donc quelque chose qui pourrait avoir un impact sur le Indice Sphinx.
Je ferais une requête pour sélectionner tous les identifiants et en utilisant cet ensemble d'identifiants, j'utiliserais la méthode "filter" sur l'API sphinx pour filtrer l'index principal jusqu'à des identifiants de document spécifiques. Une fois cela fait, vous pouvez rechercher dans Sphinx comme d'habitude. C'est la méthode la plus performante que j'ai trouvée à ce jour pour gérer cela.
L'élément clé à retenir à tout moment est que Sphinx est une technologie de recherche tandis que MySQL est une technologie de stockage. Gardez cela à l'esprit et tout devrait bien se passer.
Modifier
Comme @N.B l'a dit (ce que j'ai oublié dans ma réponse), Sphinx a SphinxSE. Bien que primitif et toujours en phase de test de son développement (comme les index en temps réel), il fournit un stockage de type MyISAM/InnoDB à Sphinx. C'est génial. Cependant, il y a des mises en garde (comme pour tout) :
- La langue est primitive
- Les jointures sont primitives
Cependant, il peut/pourrait faire le travail que vous recherchez, alors assurez-vous de l'examiner.