Optimisation d'une requête MySQL

Fermé
Tcwn32 - 7 juin 2010 à 14:28
Reivax962 Messages postés 3671 Date d'inscription jeudi 16 juin 2005 Statut Membre Dernière intervention 11 février 2021 - 7 juin 2010 à 14:52
Bonjour à tous ! :)

Je poste sur ce forum afin de vous exposer le problème auquel je suis confronté et dont je ne trouve pas de solution "raisonnable". Par "raisonnable", j'entends une solution qui ne prenne pas 10 minutes à s'exécuter en prenant 100% de l'UC.

Tout d'abord, je vais vous présenter le contexte afin que vous puissez comprendre la ou se situe mon problème. Je dispose de 3 tables MySQL dont les noms sont :
- partenaires : Cette table contient les différents partenaires du site
- referers : Cette table contient les referers, c'est à dire le site référent qui à permis l'accès au site
- sites_partenaire : Cette table contient les sites partenaires
- inscrits : Cette table contient tous les inscrits à mon site

Voici un lien vers la modélisation simplifiée de la base de donnée :
http://nsa14.casimages.com/img/2010/06/07/10060702243346490.png

Concrètement, un visiteur s'inscrit en tant que partenaire (une entrée est donc ajoutée dans la table partenaire), ajoute ces sites (autant d'entrées que de sites sont ajoutées dans la table site_partenaire). Ensuite, ce partenaire poste des liens de mon site sur son site. De mon côté, un script check les referers, si le referer n'est pas dans la table, il l'ajoute, sinon, il incrémente le compteur de visite provenant de ce referer dans la table referer. Si le visiteur s'inscrit sur mon site, alors une entrée est ajouté dans la table inscrits.

Ce que je souhaite faire, c'est mettre à jour le nombre de crédits du partenaire. Son nombre de crédits dépend du nombre de visiteurs et d'inscrits qu'il a apporté. Cependant, la mauvaise conception des tables rend la requête compliquée à mettre en oeuvre.

Dans l'hypothèse ou une visite rapporterait 10 crédit et une inscription 1000 crédits.

En gros, ce que je voudrais faire c'est un UPDATE sur la table partenaire afin de mettre à jour le nombre de credit en augmentant ce nombre de crédits de 10 x le nombre de visiteurs apporté + 1000 x le nombre d'inscrits rapportés.

Actuellement, j'effectue cette mise à jour en effectuant deux requêtes mais comme explicité plus haut, ces deux requêtes prennent près de 10 minutes à 100% du CPU pour s'exécuter, ce qui n'est pas souhaitable. Je viens donc vers vous pour tenter de trouver une meilleure solution.

Mise à jour du nombre de crédits apportés grâce au visites :

	UPDATE partenaires
	SET partenaires.credit = partenaires.credit + 10*
			(
				SELECT SUM(referers.cpt) 
				FROM referers
				JOIN sites_partenaire ON (site_partenaire.url LIKE CONCAT("%", referers.ndd, "%"))
				WHERE partenaire_id = partenaires.id
				GROUP BY(partenaire_id)
			)



Mise à jour du nombre de crédits apportés grâce aux inscriptions

	UPDATE partenaires
	SET partenaires.credit = partenaires.credit + 1000*
		(
			SELECT COUNT(*)
			FROM inscrits
			WHERE id_ref IN
			(
				SELECT id_ref
				FROM referers
				JOIN site_partenaire ON (site_partenaire.url LIKE CONCAT("%", referers.ndd, "%"))
				WHERE partenaire_id = partenaires.id
			)
		)


J'imagine que ce qui fait ralentir la requête sont les sous requêtes. D'autant plus que je souhaiterais préciser que la table "inscrits" contient plusieurs millions d'entrées.

Voila, dans l'espoir d'avoir été explicite et d'avoir de l'aide, je vous remercie d'avance :)

Encore merci de m'avoir lu.
A voir également:

2 réponses

cddu33 Messages postés 1269 Date d'inscription vendredi 11 janvier 2008 Statut Membre Dernière intervention 8 septembre 2015 256
7 juin 2010 à 14:36
se qui doit surtout ralentir tes requêtes c'est le nombre d'entrée dans ta table.

A tu déjà utilisé l'option Optimiser de Mysql
0
Reivax962 Messages postés 3671 Date d'inscription jeudi 16 juin 2005 Statut Membre Dernière intervention 11 février 2021 1 011
7 juin 2010 à 14:52
Bonjour,

Il y a en effet quelque chose de monstrueux dans tes requêtes en termes de performances, c'est ça :
JOIN sites_partenaire ON (site_partenaire.url LIKE CONCAT("%", referers.ndd, "%"))

À ta place, je rajouterais une colonne dans ta table referers qui permette de faire directement un lien entre une entrée dans cette table et un site partenaire. Par exemple en le calculant au moment où un lien entrant arrive, et, mieux, en créant une table de référence qui s'alimente automatiquement, et qui associe systématiquement un site partenaire à une entrée.

Xavier
0