Jump to content

Module lent à cause d'une requête en BDD


Recommended Posts

Bonjour
 
J'ai développé un module que j'utilise dans mes fiches produit pour afficher des produits similaires (partageant la même valeur d'une caractéristique donnée)
https://www.prestashop.com/forums/topic/536171-module-produits-similaires-par-caractéristique/
 
Je viens de me rendre compte que la lenteur de mes fiches produit vient de là. Je pense qu'il s'agit de la requête pour aller chercher les produits sans doute.
 

SELECT		p.id_product,
			p.minimal_quantity,
			p.price,
			p.wholesale_price,
			p.unity,
			p.unit_price_ratio,
			p.reference,
			p.on_sale,
			pl.description_short,
			pl.link_rewrite,
			pl.meta_description,
			pl.meta_keywords,
			pl.meta_title,
			pl.name,
			pl.name as product_name,
			i.id_image as id_image,
			fvl_rect.value as rectifie,
			fvl_dim.value as dimensions,
			fvl_solde.value as solde,
			fvl1.value as feature_value_name
			
FROM		pojs_product p
			inner join pojs_image i					on i.id_product			= p.id_product
			
			inner join pojs_product_lang pl			on p.id_product 		= pl.id_product
			inner join pojs_feature_product fp1 	on p.id_product 		= fp1.id_product
			inner join pojs_feature_value fv1		on fp1.id_feature_value = fv1.id_feature_value and fp1.id_feature = fv1.id_feature
			inner join pojs_feature_lang fl1		on fv1.id_feature		= fl1.id_feature
			inner join pojs_feature_value_lang fvl1 on fv1.id_feature_value = fvl1.id_feature_value
			
			inner join pojs_feature_product fp_rect	on fp_rect.id_product		= p.id_product
			inner join pojs_feature_value fv_rect	on fp_rect.id_feature_value	= fv_rect.id_feature_value and fp_rect.id_feature = fv_rect.id_feature
			inner join pojs_feature_lang fl_rect	on fv_rect.id_feature		= fl_rect.id_feature
			inner join pojs_feature_value_lang fvl_rect on fv_rect.id_feature_value = fvl_rect.id_feature_value
			
			inner join pojs_feature_product fp_dim	on fp_dim.id_product		= p.id_product
			inner join pojs_feature_value fv_dim	on fp_dim.id_feature_value	= fv_dim.id_feature_value and fp_dim.id_feature = fv_dim.id_feature
			inner join pojs_feature_lang fl_dim	on fv_dim.id_feature		= fl_dim.id_feature
			inner join pojs_feature_value_lang fvl_dim on fv_dim.id_feature_value = fvl_dim.id_feature_value
			
			inner join pojs_feature_product fp_solde	on fp_solde.id_product		= p.id_product
			inner join pojs_feature_value fv_solde	on fp_solde.id_feature_value	= fv_solde.id_feature_value and fp_solde.id_feature = fv_solde.id_feature
			inner join pojs_feature_lang fl_solde	on fv_solde.id_feature		= fl_solde.id_feature
			inner join pojs_feature_value_lang fvl_solde on fv_solde.id_feature_value = fvl_solde.id_feature_value

WHERE		fvl1.value	= '".$feature_value."'
			and fl1.name	= '".$feature_name."'
			and i.position 	= 1
			and fl_rect.name = 'Rectifié'
			and fl_dim.name = 'Dimensions'
			and fl_solde.name = 'solde'
			
			ORDER BY RAND()
			LIMIT 12

De quelle manière vous y prendriez vous pour ne pas plomber le serveur ?

 

Merci !

Link to comment
Share on other sites

1- entièrement d'accord avec la remarque de Mediacom87 concernant les join.

2- ORDER BY RAND() est connu pour ralentir les requêtes SQL

3- la sécurité !!! en ce moment il y a eu beaucoup de hack et ton module contient des failles, j'ai donné un exemple de faille ici : https://www.prestashop.com/forums/topic/544580-importantes-failles-de-sécurité-sur-plusieurs-modules-et-thèmes/?p=2372223 et il y a plusieurs failles de ce type dans le code.

Link to comment
Share on other sites

Ouah cette requête, pas étonnant, il faut simplifié tout ca et passé par d'autre moyen, tableau php etc... faut mieux faire plein de petit requête qu'une très grosse.

 

Quand je gérai un très à très fort trafic (notamment un script appelé 5 millions de fois par jour), l'hébergeur ne voulais pas une seule jointure en SQL

Link to comment
Share on other sites

Tu as raison. Je n'y connais rien en SQL mais j'ai refais ceci : 

SELECT		p.id_product,
			p.minimal_quantity,
			p.price,
			p.wholesale_price,
			p.unity,
			p.unit_price_ratio,
			p.reference,
			p.on_sale,
			pl.description_short,
			pl.link_rewrite,
			pl.meta_description,
			pl.meta_keywords,
			pl.meta_title,
			pl.name,
			pl.name as product_name,
			i.id_image as id_image,
			fvl_rect.value as rectifie,
			fvl_dim.value as dimensions,
			fvl_solde.value as solde,
			fvl1.value as feature_value_name
			
FROM		pojs_product p
			inner join pojs_image i					on i.id_product			= p.id_product
			
			inner join pojs_product_lang pl			on p.id_product 		= pl.id_product
			
			inner join pojs_feature_product fp1 fp_rect fp_dim fp_solde 	on p.id_product = fp1.id_product = fp_rect.id_product = fp_dim.id_product = fp_solde.id_product
			
			inner join pojs_feature_value fv1 fv_rect fv_dim fv_solde on 
			fp1.id_feature_value = fv1.id_feature_value and fp1.id_feature = fv1.id_feature 
			and fp_rect.id_feature_value = fv_rect.id_feature_value and fp_rect.id_feature = fv_rect.id_feature 
			and fp_dim.id_feature_value	= fv_dim.id_feature_value and fp_dim.id_feature = fv_dim.id_feature 
			and fp_solde.id_feature_value	= fv_solde.id_feature_value and fp_solde.id_feature = fv_solde.id_feature
			
			inner join pojs_feature_lang fl1 fl_rect fl_dim fl_solde on fv1.id_feature = fl1.id_feature and  fv_rect.id_feature = fl_rect.id_feature and fv_dim.id_feature = fl_dim.id_feature and fv_solde.id_feature		= fl_solde.id_feature			
			inner join pojs_feature_value_lang fvl1 fvl_rect fvl_dim fvl_solde on fv1.id_feature_value = fvl1.id_feature_value and fv_rect.id_feature_value = fvl_rect.id_feature_value and fv_dim.id_feature_value = fvl_dim.id_feature_value and fv_solde.id_feature_value = fvl_solde.id_feature_value

WHERE		fvl1.value	= '".$feature_value."'
			and fl1.name	= '".$feature_name."'
			and i.position 	= 1
			and fl_rect.name = 'Rectifié'
			and fl_dim.name = 'Dimensions'
			and fl_solde.name = 'solde'
			
			ORDER BY RAND()
			LIMIT 12

En revanche ça n'a rien changé niveau performance.

Link to comment
Share on other sites

nner join pojs_feature_value fv1 fv_rect fv_dim fv_solde on

            fp1.id_feature_value = fv1.id_feature_value and fp1.id_feature = fv1.id_feature

            and fp_rect.id_feature_value = fv_rect.id_feature_value and fp_rect.id_feature = fv_rect.id_feature

            and fp_dim.id_feature_value    = fv_dim.id_feature_value and fp_dim.id_feature = fv_dim.id_feature

            and fp_solde.id_feature_value    = fv_solde.id_feature_value and fp_solde.id_feature = fv_solde.id_feature

 

 

ca reste des jointures

Link to comment
Share on other sites

Bonjour et merci pour les retours.

Désolé je n'avais vu que le message de Mediacom87 avant de simplifier ma requête.

 

J'envisage de refaire ce plugin différemment, c'est à dire que je générerai une table de correspondance via le backoffice (id, feature_name, feature_value, product_ids) une seule fois, manuellement, puis je n'aurai qu'à piocher les product_ids correspondant une fois sur ma page produit. La génération risque de prendre quelques secondes et est à refaire lors d'ajout de nouveaux produits, mais c'est juste une fois de temps en temps.

 

Ci-joint, un jpg pour illustrer la table "ps_plugin_relatedfeatures"

 

Mettons ensuite que j'affiche un produit dont la caractéristique "Collection" a pour valeur "Lazio", le plugin n'a qu'à charger le champ product_ids correspondant et de récupérer les infos produits.

 

Ca vous semble être une bonne solution ?

post-1248856-0-89418800-1469520831_thumb.jpg

Link to comment
Share on other sites

Plugin refait à 100% (en PJ)

Impact négligeable sur le temps de réponse du serveur  B)

 

C'est très certainement améliorable mais ça me va comme ça.

Si quelqu'un veut l'utiliser, il y a un peu de code à supprimer dans "featurebuddy.php" (c'est commenté).

En revanche il faudra faire un peu plus de ménage dans "featurebuddy.tpl" car j'y affiche des caractéristiques, et surtout les prix risques d'être faux car j'ai changé le calcul sur ma boutique. Rien de compliqué.

featurebuddy.zip

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...