2011-04-19 3 views
2

Je fais une recherche fulltext mysql.Comment optimiser la recherche d'union mysql fulltext?

ma table de base de données article1 a ~18000 articles, article2 a ~7000 articles, article3 a ~13000 articles. FIELD cat est un champ INDEX

Maintenant, je veux faire une recherche de syndicat. il y a 5 groupes de mots mis dans 3 table, faire correspondre les résultats. Mais le temps de traitement est 3.1213495136 seconds. (J'ajoute microtime() pour voir combien de temps ça va coûter). Est-il possible d'optimiser la recherche d'union mysql fulltext? Merci.

(SELECT title,content,date FROM article1 WHERE 
(cat='novel' AND MATCH (title,content) AGAINST ('+Mary +Barnard' IN BOOLEAN MODE)) 
OR 
(cat='novel' AND MATCH (title,content) AGAINST ('+Patricia +Beer' IN BOOLEAN MODE)) 
OR 
(cat='novel' AND MATCH (title,content) AGAINST ('+Aphra +Behn' IN BOOLEAN MODE)) 
OR 
(cat='novel' AND MATCH (title,content) AGAINST ('+Judy +Blume' IN BOOLEAN MODE)) 
OR 
(cat='novel' AND MATCH (title,content) AGAINST ('+Elizabeth +Bowen' IN BOOLEAN MODE))) 
UNION 
(SELECT title,content,date FROM article2 WHERE 
(MATCH (title,content) AGAINST ('+Mary +Barnard' IN BOOLEAN MODE)) 
OR 
(MATCH (title,content) AGAINST ('+Patricia +Beer' IN BOOLEAN MODE)) 
OR 
(MATCH (title,content) AGAINST ('+Aphra +Behn' IN BOOLEAN MODE)) 
OR 
(MATCH (title,content) AGAINST ('+Judy +Blume' IN BOOLEAN MODE)) 
OR 
(MATCH (title,content)AGAINST ('+Elizabeth +Bowen' IN BOOLEAN MODE))) 
UNION 
(SELECT title,content,date FROM article3 WHERE 
(MATCH (title,content) AGAINST ('+Mary +Barnard' IN BOOLEAN MODE)) 
OR 
(MATCH (title,content) AGAINST ('+Patricia +Beer' IN BOOLEAN MODE)) 
OR 
(MATCH (title,content) AGAINST ('+Aphra +Behn' IN BOOLEAN MODE)) 
OR 
(MATCH (title,content) AGAINST ('+Judy +Blume' IN BOOLEAN MODE)) 
OR 
(MATCH (title,content)AGAINST ('+Elizabeth +Bowen' IN BOOLEAN MODE))) 
Order By date DESC LIMIT 10 
+0

Je vous suggère de passer à un serveur externe de recherche de texte intégral tel que sphinxsearch.com. D'après mon expérience, le sphinx sera x fois plus rapide que la recherche en texte intégral mysql. –

Répondre

3

La première chose que vous devez faire est d'ajouter

Order By date DESC LIMIT 10 

dans chaque sous-requête que vous n'avez pas besoin de plus de 10 résultats à la fin.

Il doit également y avoir des index sur les champs "date" dans toutes les tables.

alter table "TABLENAME" add index date_idx(date); 

plus:

Vous pouvez raccourcir et accélérer un peu, il demande en modifiant les termes de recherche à la forme: "() |()"

(SELECT title,content,date FROM article1 WHERE 
(cat='novel' AND MATCH (title,content) AGAINST ('(+Mary +Barnard) | (+Patricia +Beer) | (+Aphra +Behn) | (+Judy +Blume) | (+Elizabeth +Bowen)' IN BOOLEAN MODE)) 
Order By date DESC LIMIT 10) 
UNION 
(SELECT title,content,date FROM article2 WHERE 
(MATCH (title,content) AGAINST ('(+Mary +Barnard) | (+Patricia +Beer) | (+Aphra +Behn) | (+Judy +Blume) | (+Elizabeth +Bowen)' IN BOOLEAN MODE)) 
Order By date DESC LIMIT 10) 
UNION 
(SELECT title,content,date FROM article3 WHERE 
(MATCH (title,content) AGAINST ('(+Mary +Barnard) | (+Patricia +Beer) | (+Aphra +Behn) | (+Judy +Blume) | (+Elizabeth +Bowen)' IN BOOLEAN MODE)) 
Order By date DESC LIMIT 10) 
Order By date DESC LIMIT 10 
+0

@Andriy Bohdan, excusez-moi, est-il nécessaire de changer les champs "date" en 'INDEX'. chaque date d'article est différente. Est-ce que cela peut aider la requête plus rapidement? Merci. – cj333

+0

@ cj333 oui, ça peut vraiment aider. – Emmerman

+0

Il est possible que l'index à la date ne donne aucun effet. La meilleure façon de savoir est de tester la requête avec index et sans elle. Pour voir si l'index aide ou non, vous pouvez exécuter EXPLAIN et vérifier si mysql utilise index à la date ou non. –

1

Une alternative à votre syndicat serait de effectuez ces recherches séparément. Si vous commandez vos critères par pertinence, le premier jeu est le meilleur; retourner les résultats partiels et seulement s'il y en a moins de 10, essayer la prochaine correspondance, etc.

Ensuite, la requête est rapide pour l'utilisateur final, renvoie les résultats dans l'ordre de pertinence, et ne gaspille pas les ressources MySQL à obtenir des données indésirables. Si l'utilisateur en demande plus, une requête plus longue et inefficace peut s'exécuter, mais elle a alors un sens.