2010-08-19 11 views
0

Je suis en train de réviser ma question il y a quelques jours. Réécrit ma requête. Est-ce que quelqu'un peut me dire pourquoi courir n'importe quel type de requête sur plusieurs tables prend tellement de temps en utilisant la requête que je posterai ci-dessous?Revisiting MySQL Multiple Match Query .... prend tellement de temps

Y a-t-il quelqu'un qui a le temps de m'aider? Je peux payer 200 $. Je me dis que c'est bon pour deux heures de travail. Je posterai la réponse ici pour que tout le monde en profite.

La requête est essentiellement ceci:

SELECT bb_business.business_name, bb_business.id AS bid FROM bb_business 
LEFT JOIN bb_offers  ON bb_business.id = bb_offers.store_id 
LEFT JOIN bb_cat_business ON bb_business.id = bb_cat_business.store_id 
LEFT JOIN bb_categories ON bb_categories.id = bb_cat_business.cat_id 
WHERE bb_business.active = '1' 
    AND MATCH(bb_business.business_name) AGAINST ('zebra') 
    OR MATCH(bb_categories.category_name) AGAINST ('zebra') 
    OR MATCH (bb_business.city,bb_business.state,bb_business.zip) AGAINST ('zebra') 
GROUP BY bb_business.business_name 
ORDER BY bb_business.business_name DESC 
LIMIT 1,10 

Cette requête prend 50 secondes pour exécuter la première fois. La deuxième fois c'est rapide comme prévu.

Si je modifie cette requête pour n'utiliser qu'une correspondance, elle est rapide. Dès que j'ajoute une deuxième instruction MATCH ou LIKE, cela revient à 40-60 temps d'exécution.

L'exécution de cette requête exacte tourne à: MySQL returned an empty result set (i.e. zero rows). (Query took 47.7614 sec)

EXPLAIN retourne ceci:

1 SIMPLE bb_business ALL NULL NULL NULL NULL 2877 Using temporary; Using filesort 
1 SIMPLE bb_offers ALL NULL NULL NULL NULL 94 
1 SIMPLE bb_cat_business ALL NULL NULL NULL NULL 5697 
1 SIMPLE bb_categories eq_ref PRIMARY PRIMARY 8 buxback_site.bb_cat_business.cat_id 1 Using where 

Lorsque vous utilisez une seule correspondance, la requête utilise un index de texte intégral que j'ai sur bb_business. Lorsque j'ai plusieurs correspondances, il ne semble pas utiliser d'index.

Voici les indices sur bb_business:

PRIMARY PRIMARY 2877  id 
store_id UNIQUE 2877  store_id 
index_business_name INDEX 2877  business_name 
business_name FULLTEXT 1  business_name 
city FULLTEXT 1  city 
state 
zip 

Voici les indices sur bb_categories:

PRIMARY PRIMARY 15  id 
category_name UNIQUE None  category_name 
category_name_2 FULLTEXT None  category_name 

Je suis desparate!

Merci!

+0

Si vous voulez contacter mon directement envoyer à senica à allebrum.com –

Répondre

1

Le problème est que vous obligez MySQL à créer des tables temporaires pour résoudre la requête. C'est à peu près un problème tant que vous faites plusieurs matchs.

Si votre cas d'utilisation vous oblige vraiment à le faire, vous avez deux options principales (que je peux voir).

  1. Créez un tableau récapitulatif dénormalisé dans lequel vous pouvez placer un index de texte intégral sur toutes les colonnes que vous devez comparer. Ensuite, gardez cette table mise à jour (soit par des déclencheurs, des procédures stockées, ou juste diligence lorsque vous exécutez vos requêtes dans le code) ... Ensuite, faites toutes les correspondances avec cette table récapitulative (il faut éliminer plusieurs clauses MATCH requête) ...
  2. L'autre option serait d'utiliser un moteur de recherche dédié, comme Apache SOLR ou Sphinx. Vous auriez besoin de chercher séparément, puis de retirer les résultats de la base de données, mais ces moteurs de recherche sont beaucoup plus puissants que MySQL (bien, pas puissant, mais plus facile à faire), et beaucoup plus rapide que MySQL pour exécuter ces requêtes . Ils peuvent le faire parce qu'ils pré-indexent everyting (ils sacrifient l'espace disque -parfois beaucoup- pour la vitesse) ...
+0

J'ai terminé en ajoutant un tableau récapitulatif. J'ai bien travaillé et mes temps de travail sont assez rapides.Merci pour votre suggestion et confirmant ce que je voyais. –

+0

Pourriez-vous publier un lien sur les tableaux récapitulatifs? Je pense que je dois le faire mais je ne trouve rien sur google – NaturalBornCamper