2010-11-05 11 views
1

J'ai une base de données mais je prévois un problème de vitesse. Parce que toutes mes données sont sauvegardées séparémentOptimiser la requête Mysql dans une base de données de valeurs d'attributs

Product table: 
id int auto_inc PRI 
name var_char(64) 

attribute_table: 
attr_id int auto_inc PRI 
name var_char(64) 

attribute_value: 
attr_id int 
product_id 
value 

mais quand je fais une recherche avancée je reçois querys ENORM comme

select * from product_table as pt 
cross join attribute_value as av ON av.product_id = pt.id AND av.value LIKE "test" 
cross join attribute_table as at ON at.attr_id = av.attr_id AND at.name = "test" 
cross join attribute_value as av ON av.product_id = pt.id AND av.value LIKE "test2" 
cross join attribute_table as at ON at.attr_id = av.attr_id AND at.name = "test2" 
cross join attribute_value as av ON av.product_id = pt.id AND av.value LIKE "test3" 
cross join attribute_table as at ON at.attr_id = av.attr_id AND at.name = "test3" 

mais je suppose que ce isnt vraiment rapide. mais y a-t-il un moyen d'optimiser? ou quelques trucs que je peux utiliser pour chercher plus vite comme une sorte d'encaissement?

+0

Qu'est-ce que votre requête est censée faire exactement? Vous voulez probablement utiliser LEFT JOIN, et probablement vouloir ajouter des index, mais jusqu'à ce que je puisse comprendre ce que vous essayez de sélectionner je ne peux pas vraiment vous aider. –

Répondre

0

Je crois que vous voulez faire quelque chose comme:

select * from product_table as pt JOIN attribute_value as av 
    ON av.product_id = pt.id 
WHERE (av.value LIKE "test") 
    OR (at.name = "test") 
    OR (av.value LIKE "test2") 
    OR (at.name = "test2") .... 

qui vous fait un joindre, avec une sélection du résultat. Je pense que c'est plus proche de ce que tu veux.

0

D'abord, je réécris (je ne comprends pas pourquoi vous rejoignez les mêmes tables plusieurs fois):

select * from product_table as pt 
INNER join attribute_value as av ON (av.product_id = pt.id AND av.value LIKE "test%") 
INNER join attribute_table as at ON (at.attr_id = av.attr_id AND at.name LIKE "test%") 

Ensuite, exécutez EXPLAIN SELECT ... pour vérifier plaine d'exécution. Il montre quels index sont actuellement utilisés pour la requête.
Ensuite, assurez-vous que vous avez des index sur les colonnes qui sont utilisées pour joindre des tables - vous devriez avoir des index (au moins) sur attribute_value.product_id, attribute_table.attr_id.
Enfin, sélectionnez uniquement ce dont vous avez besoin, et non *.