Recherche plein texte avec InnoDB


93

Je développe une application Web à haut volume, dont une partie est une base de données MySQL de messages de discussion qui devront passer à plus de 20 millions de lignes, en douceur.

J'avais initialement prévu d'utiliser MyISAM pour les tables (pour les capacités de recherche de texte intégral intégrées ), mais l'idée que la table entière soit verrouillée en raison d'une seule opération d'écriture me fait fermer. Les verrous au niveau des lignes ont tellement plus de sens (sans parler des autres avantages de vitesse d'InnoDB lorsqu'il s'agit de tables énormes). Donc, pour cette raison, je suis assez déterminé à utiliser InnoDB.

Le problème est ... InnoDB n'a pas de capacités de recherche plein texte intégrées.

Dois-je utiliser un système de recherche tiers? Comme Lucene (c ++) / Sphinx ? L'un de vous ninjas de la base de données a-t-il des suggestions / conseils?Le zoie de LinkedIn (basé sur Lucene) semble être la meilleure option pour le moment... ayant été construit autour de capacités temps réel (ce qui est assez critique pour mon application.) J'hésite un peu à m'engager mais sans une certaine perspicacité ...

(FYI: va être sur EC2 avec des rigs à haute mémoire, en utilisant PHP pour servir le frontend)


Réponses:


50

Je peux garantir que le texte intégral MyISAM est une mauvaise option - même en laissant de côté les divers problèmes avec les tables MyISAM en général, j'ai vu le texte intégral dérailler et commencer à se corrompre et à planter MySQL régulièrement.

Un moteur de recherche dédié sera certainement l'option la plus flexible ici - stocker les données de publication dans MySQL / innodb, puis exporter le texte vers votre moteur de recherche. Vous pouvez configurer assez facilement une compilation / publication d'index complète périodique et ajouter des mises à jour d'index en temps réel si vous en ressentez le besoin et que vous souhaitez passer du temps.

Lucene et Sphinx sont de bonnes options, tout comme Xapian , qui est agréable et léger. Si vous suivez la voie Lucene, ne supposez pas que Clucene ira mieux, même si vous préférez ne pas lutter avec Java, même si je ne suis pas vraiment qualifié pour discuter des avantages et des inconvénients de l'un ou l'autre.


7
Solr (basé sur Lucene) peut évoluer énormément et est très puissant et flexible. Nous avons utilisé Solr (en particulier l'édition LucidWorks pour Solr) et je peux dire que cela a été une énorme victoire. Sphinx a également de sérieuses promesses mais finalement son manque de types de données peut être troublant, du moins pour notre application. Sphinx est très rapide et s'il répond à vos besoins, c'est également un choix solide.
Cody Caughlan

Merci beaucoup vous deux; bonnes réponses. J'ai feuilleté les documents de Solr, et cela semble être une excellente solution. Cela alimente également quelques sites Web énormes, je vois. Je pense que Solr est le ticket. Merci les gars. Aussi, il est bon d'apprendre de vos maux de tête MyISAM, Ian ... ceux-ci seront bons à avoir à l'esprit dans le futur. Sur d'autres projets, je m'éloignerai de l'idée d'utiliser la fonctionnalité de texte intégral.
brianreavis le

11
Vous vous demandez ce qui a fait dire à Ian "ne présumez pas que Clucene va mieux"? en tant que membre de l'équipe principale de clucene, je ne suis peut-être pas aussi objectif, mais il me semble que le port C ++ optimisé de toute bibliothèque Java augmentera ses performances à travers le toit. Je recommanderais à quiconque de ne pas publier de tels commentaires sans avoir au moins un coup d'œil sur le produit qu'ils déshonorent.
synhershko

4
Lorsque vous claquez MyISAM, vous devez vraiment être plus précis. «Off the rails» est très vague, et peut être dû à un seul bogue dans la version que vous utilisiez, peut-être corrigé depuis.
bobobobo

6
Mais que se passe-t-il si vous n'avez pas la possibilité d'installer un logiciel sur le serveur - quelles alternatives existent dans ce cas?
acme

56

Parallèlement à la suppression progressive de MyISAM, la recherche de texte intégral InnoDB (FTS) est enfin disponible dans la version MySQL 5.6.4.

Beaucoup de détails juteux sur https://dev.mysql.com/doc/refman/5.6/en/innodb-fulltext-index.html .

Alors que d'autres moteurs ont beaucoup de fonctionnalités différentes, celui-ci est InnoDB, donc il est natif (ce qui signifie qu'il y a un chemin de mise à niveau), et cela en fait une option intéressante.


1
Le lien de l'article est 403 interdit
Marco Demaio

11

Vous devriez passer une heure et passer par l'installation et l'essai routier de Sphinx et Lucene. Voyez si l'un ou l'autre répond à vos besoins en matière de mise à jour des données

L'une des choses qui m'a déçu à propos de Sphinx est qu'il ne prend pas très bien en charge les insertions incrémentielles. Autrement dit, il est très coûteux de réindexer après une insertion, si cher que la solution recommandée consiste à diviser vos données en lignes plus anciennes et inchangées et en lignes plus récentes et volatiles. Ainsi, chaque recherche effectuée par votre application devrait effectuer deux recherches: une fois sur l'index le plus grand pour les anciennes lignes et également sur l'index le plus petit pour les lignes récentes. Si cela ne s'intègre pas à vos modèles d'utilisation, ce Sphinx n'est pas une bonne solution (du moins pas dans son implémentation actuelle).

Je voudrais souligner une autre solution possible que vous pourriez envisager: la recherche personnalisée Google . Si vous pouvez appliquer un peu de référencement à votre application Web, sous-traitez la fonction d'indexation et de recherche à Google et intégrez un champ de texte de recherche Google dans votre site. Cela pourrait être le moyen le plus économique et le plus évolutif de rendre votre site consultable.


Merci, Bill. Oui, la documentation Sphinx m'a fait hésiter un peu sur la façon dont elle gère les mises à jour d'index. C'est bien de le faire confirmer. Ce genre de système deviendrait probablement un cauchemar pour moi, j'imagine. Quant à la recherche personnalisée Google, c'est une option. Cependant, mon principal problème avec cela est juste l'index non-temps réel et le manque de personnalisation. Styliser les résultats et extraire des données supplémentaires sera assez crucial pour moi. Merci de votre participation - les informations sur le Sphinx sont certainement bonnes à savoir!
brianreavis le

3

Peut-être ne devriez-vous pas rejeter le FT de MySQL si rapidement. Craigslist l'utilisait .

La vitesse de MySQL et la recherche en texte intégral ont permis à craigslist de servir ses utilisateurs. Craigslist utilise MySQL pour traiter environ 50 millions de recherches par mois à un taux allant jusqu'à 60 recherches par seconde. "

Éditer

Comme commenté ci-dessous, Craigslist semble être passé à Sphinx au début de 2009.


L'article que j'ai lié ne mentionne pas Sphinx, et Nik ne cite aucune source indiquant que Craigslist utilise Sphinx du tout
bobobobo

L'étude de cas PDF ressemble à 2004, date à laquelle il y avait 50 millions de recherches par mois. La page Sphinx indique 50 millions de recherches par jour , ce qui explique probablement la raison pour laquelle ils sont passés à une solution de recherche dédiée.
Halil Özgür

1

Sphinx, comme vous le faites remarquer, est assez sympa pour ce genre de choses. Tout le travail est dans le fichier de configuration. Assurez-vous que quelle que soit votre table avec les chaînes, elle possède une clé d'identifiant d'entier unique, et tout devrait bien se passer.


0

essaye ça

ROUND((LENGTH(text) - LENGTH(REPLACE(text, 'serchtext', ''))) / LENGTH('serchtext'),0)!=0

0

Vous devriez jeter un oeil à Sphinx. Cela vaut la peine d'essayer. Son indexation est super rapide et elle est distribuée. Vous devriez jeter un œil à ce webminar (http://www.percona.com/webinars/2012-08-22-full-text-search-throwdown). Il parle de recherche et a quelques points de repère intéressants. Vous pouvez trouver cela utile.



0

Pour toute personne bloquée sur une ancienne version de MySQL / MariaDB (c'est-à-dire les utilisateurs CentOS) où InnoDB ne prend pas en charge les recherches Fulltext, ma solution lors de l'utilisation des tables InnoDB était de créer une table MyISAM séparée pour ce que je voulais rechercher.

Par exemple, ma table InnoDB principale était productsavec diverses clés et intégrité référentielle. J'ai ensuite créé une simple table MyISAM appelée product_searchcontenant deux champs, product_idet product_nameoù ce dernier était défini sur un FULLTEXTindex. Les deux champs sont en fait une copie de ce qui se trouve dans la producttable principale .

Je recherche ensuite sur la table MyISAM en utilisant le texte intégral, et je fais une jointure interne vers la table InnoDB.

Le contenu de la table MyISAM peut être tenu à jour via des déclencheurs ou le modèle de l'application.

Je ne le recommanderais pas si vous avez plusieurs tables qui nécessitent du texte intégral, mais pour une seule table, cela semble être un travail adéquat jusqu'à ce que vous puissiez mettre à niveau.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.