2010-05-28 5 views
0

J'ai une requête sql que j'ai du mal à optimiser. Il est essentiellement utilisé pour retirer des produits pour un panier. Les produits ont chacun des balises attachées en utilisant une table product_tag de plusieurs à plusieurs et je retire également un nom de magasin d'une table de magasin séparée. Im en utilisant group_concat pour obtenir une liste de balises pour l'affichage (c'est pourquoi j'ai les étranges clauses groupby orderby en bas) et j'ai besoin de commander par dateadded, montrant le dernier produit planifié en premier. Voici la requête ....MySql product tag optimisation de requête

SELECT `products`.*, `stores`.`name`, GROUP_CONCAT(tags.taglabel ORDER BY tags.id ASC SEPARATOR " ") taglist 
FROM (`products`) 
JOIN `product_tag` ON `products`.`id`=`product_tag`.`productid` 
JOIN `tags` ON `tags`.`id`=`product_tag`.`tagid` 
JOIN `stores` ON `products`.`cid`=`stores`.`siteid` 
WHERE `dateadded` < '2010-05-28 07:55:41' 
GROUP BY `products`.`id` ASC 
ORDER BY `products`.`dateadded` DESC 
LIMIT 2 

Malheureusement, même avec un petit ensemble de données (3 balises et environ 12 produits) la requête prend 00.0034 secondes pour exécuter. Finalement, je veux avoir environ 2000 produits et 50 étiquettes dans ce système (je suppose que ce sera très slooooow). Voici le ExplainSql ...

id|select_type|table|type|possible_keys|key|key_len|ref|rows|Extra 
1|SIMPLE|tags|ALL|PRIMARY|NULL|NULL|NULL|4|Using temporary; Using filesort 
1|SIMPLE|product_tag|ref|tagid,productid|tagid|4|cs_final.tags.id|2| 
1|SIMPLE|products|eq_ref|PRIMARY,cid|PRIMARY|4|cs_final.product_tag.productid|1|Using where 
1|SIMPLE|stores|ALL|siteid|NULL|NULL|NULL|7|Using where; Using join buffer 

Quelqu'un peut-il aider?

+0

Les devinettes ne s'adaptent pas bien. Si vous voulez savoir comment le système fonctionnera avec 2000 produits et 50 étiquettes, générez autant de données d'exemple. Générez, disons, 10K exemples de transactions, et exécutez votre requête sur les exemples en utilisant la requête EXPLAIN de MySQL. Répétez avec 100K et avec des transactions 1M. –

Répondre

0

IMO, vous n'avez pas besoin de s'inquiéter.

  • Avoir 2 000 produits ne prendrait PAS 100 fois plus longtemps que 20 produits. C'est ce que sont les index (et les bases de données, vraiment ...). 2000 enregistrements est toujours une très petite table pour MySQL.

Je pense que vous pouvez laisser la requête telle quelle et vous verrez bientôt qu'elle fonctionne bien.

Une seule fois le jeu de résultats obtient vraiment grand (plus grand que la mémoire du système - par exemple plusieurs SGB), le tri peut prendre un certain temps car le DB utilisera le disque, c'est quand vous pouvez commencer à se soucier. Dans ce cas, il est parfois utile de créer une table temporaire pour les résultats non triés, d'y ajouter un index et de les sélectionner avec ORDER BY.