requête mysql en prenant 30 secondes pour exécuter ... trop long

voix
0

Je suis en train d'exécuter une requête MySQL comme une recherche sur un site et il est en train de prendre beaucoup de temps.

Je courus directement à partir de phpMyAdmin et il a fallu environ 20 secondes.

Voici la requête que je suis en cours d'exécution:

SELECT * , bb_business.id AS bid
FROM bb_business
LEFT OUTER JOIN bb_offers ON bb_business.id = bb_offers.store_id
LEFT OUTER JOIN bb_cat_business ON bb_business.id = bb_cat_business.store_id
LEFT OUTER JOIN bb_categories ON bb_categories.id = bb_cat_business.cat_id
WHERE bb_business.active = '1'
AND (
bb_business.business_name LIKE '%altas%'
OR bb_categories.category_name LIKE '%altas%'
OR bb_business.business_name LIKE '%juice%'
OR bb_categories.category_name LIKE '%juice%'
)
AND (
bb_business.city LIKE '%%'
OR bb_business.state LIKE '%%'
OR bb_business.zip LIKE '%%'
)
GROUP BY bb_business.business_name
ORDER BY bb_business.business_name DESC 
LIMIT 1 , 10`

Vitesse: Affichage des lignes 0 - 0 (1 au total, requête a pris 20,1130 s)

Je ne sais pas la meilleure façon de vous montrer la structure. Mais ici un copier-coller pour la collation de quelques-uns des tableaux:

bb_ach            128 InnoDB latin1_swedish_ci 32.0 KB - 
bb_business       2,862 InnoDB latin1_swedish_ci 1.6 MB - 
bb_categories     15 MyISAM utf8_general_ci 6.7 KB 60 Bytes

bb_cat_business   2,926 MyISAM utf8_general_ci 49.6 KB 17 Bytes

bb_emails         13 MyISAM utf8_general_ci 6.0 KB - 
bb_member         409 MyISAM utf8_general_ci 62.7 KB - 
bb_member_card    593 MyISAM utf8_general_ci 112.1 KB - 
bb_merchant       154 InnoDB latin1_swedish_ci 32.0 KB - 
bb_offers         80 InnoDB latin1_swedish_ci 16.0 KB - 
bb_products       2 InnoDB latin1_swedish_ci 32.0 KB 

Si je peux fournir quoi que ce soit d'autre. S'il vous plaît, faites-moi savoir.

Merci beaucoup pour toute aide.

MODIFIER##################################

D'accord, en utilisant la suggestion Poneys OMG, j'ai changé quelques petites choses. A fait quelques MyISAM choses et créé quelques index FULLTEXT à utiliser.

J'ai fini avec cette requête:

SELECT *, bb_business.id AS bid FROM bb_business 
LEFT OUTER JOIN bb_offers ON bb_business.id = bb_offers.store_id 
LEFT OUTER JOIN bb_cat_business ON bb_business.id = bb_cat_business.store_id 
LEFT OUTER JOIN bb_categories ON bb_categories.id = bb_cat_business.cat_id 
WHERE bb_business.active = '1' AND 
MATCH(bb_business.business_name) AGAINST ('.addslashes($business).') OR 
MATCH(bb_categories.category_name) AGAINST ('.addslashes($business).') OR 
MATCH (bb_business.city,bb_business.state,bb_business.zip) AGAINST ('.addslashes($city).') 
GROUP BY bb_business.business_name 
ORDER BY bb_business.imported,.$this->sortCol. .$this->sortDirection. LIMIT .$this->start.,.$this->limit

Je pense qu'il a rendu encore plus lent;)

Le EXPLIQUER donne ceci:

id  select_type  table  type  possible_keys  key  key_len  ref  rows  Extra  
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 

Ainsi, le résultat est que la première requête prendre jusqu'à 40 secondes. Si je recherche la même phrase exacte à nouveau, la vitesse est que je me attends MYSQL à effectuer. Dans les millisecondes. Il est juste la première recherche qui prend toujours ...

Toutes les autres pensées? Je serais heureux de payer quelqu'un pour aider.

Créé 17/08/2010 à 16:41
source utilisateur
Dans d'autres langues...                            


3 réponses

voix
2

Prendre la requête à la valeur nominale, voici ma re-écriture:

   SELECT *, bb_business.id AS bid
     FROM bb_business b
LEFT JOIN bb_offers o ON o.store_id = b.id
LEFT JOIN bb_cat_business cb ON cb.store_id = b.id
LEFT JOIN bb_categories c ON c.id = cb.cat_id
    WHERE b.active = '1'
      AND (    bb_business.business_name LIKE '%altas%'
            OR bb_business.business_name LIKE '%juice%'
            OR MATCH(c.category_name) AGAINST ('altas', 'juice'))          
 GROUP BY b.business_name
 ORDER BY b.business_name DESC 
    LIMIT 0, 10
  • LIMIT commence à zéro - en commençant par un omettra le premier enregistrement.
  • Vous pouvez utiliser la fonctionnalité de recherche Texte intégral (FTS) sur les tables MyISAM, qui est ce que l' MATCH() .. AGAINSTest. Vous pouvez le faire plus rapidement en ajoutant un indice de texte intégral ...
  • SELECT * est une mauvaise approche - mieux préciser tous que vous voulez réellement
Créé 17/08/2010 à 16:56
source utilisateur

voix
1

Utilisez EXPLIQUER pour voir ce qui se passe, comment la base de données est en cours d'exécution de votre base de données.

LIKE tuer les performances, la base de données ne peut pas utiliser un index lorsque votre paramètre commence par%.

Créé 17/08/2010 à 17:23
source utilisateur

voix
0

Je voulais juste revenir et revist cela et poster une réponse. J'ai fini par créer une table d'index et créé un script PHP pour indexer la base de données principale. L'essentiel est que MySQL n'a pas fait un bon travail de manipulation de correspondances multiples sur plusieurs tables.

Créé 06/10/2010 à 15:01
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more