Performance d'une requete de mise à jour

Eléphant du PHP | 94 Messages

18 janv. 2009, 22:49

Bonjour à tous

J'ai un problème de performance d'une requête de mise à jour d'une table mysql via php.

Je dispose d'une table avec 6000 enregistrements.
Il s'agit d'une liste de boutiques. Une même boutique peut apparaitre plusieurs fois selon le profil de clients à qui elle s'adresse (Particulier, Professionnel, Association, Entrepreneur).
Ainsi une même boutique peut apparaitre 4 fois si elles s'adressent aux 4 profils.

J'ai voulu créé une table avec la liste des boutiques dédoublonnées (elle fait 2000 enregistrements). J'ai créé dans cette table un champ par profil que je veux remplir à 1 si la boutique concerne ce profil.

J'ai donc créé un lien entre la table sans doublons et la table d'origine pour faire la mise à jour :
$type = array('Associations','Entrepreneurs','Professionnels','Particuliers');
			for ($i=0; $i<4 ; $i++)
			{
				$a=strtolower($type[$i]);
	
				$sql ="select * from source_boutique"
						. " INNER JOIN boutique ON source_boutique.code=boutique.code"
						. " WHERE source_boutique.type_client = '$type[$i]'";

				$resultat=ExecRequete ($sql, $connexion);
				while ($tmp = mysql_fetch_array($resultat))
				{	
					$rq="UPDATE pdv SET $a='1'";
					ExecRequete ($rq, $connexion);
				} 
			}	
Cette requête met plus de 30 secondes à s'effectuer. Compte tenu du nombre d'enregistrements concernés je suis étonné. D'autant que lorsque je lance des requetes simples sur tous les enregistrements directement dans mysql elles s'éxécutent très rapidement.
Je pense avoir indéxé ma table correctement (sur le champ code)

Est ce mon code PHP qui provoque cette durée de requête ?
Cela peut il être amélioré ?
Est ce un problème de code php qui n'est pas optimisé ?

A noter que cette performance est constaté sur wamp en local sur mon poste.

Code : Tout sélectionner

CREATE TABLE `boutique` ( `ligne` int(11) NOT NULL AUTO_INCREMENT, `nom` varchar(128) NOT NULL DEFAULT '', `code` varchar(8) NOT NULL DEFAULT '', `adresse` varchar(128) NOT NULL DEFAULT '', `ville` varchar(32) NOT NULL DEFAULT '', `cp` varchar(5) NOT NULL DEFAULT '', `fax` varchar(32) NOT NULL DEFAULT '', `client` varchar(3) NOT NULL DEFAULT '', `particuliers` varchar(1) NOT NULL, `professionnels` varchar(1) NOT NULL, `entrepreneurs` varchar(1) NOT NULL, `associations` varchar(1) NOT NULL, `maj` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`ligne`), KEY `code` (`code`), KEY `associations` (`associations`), KEY `particuliers` (`particuliers`), KEY `professionnels` (`professionnels`), KEY `entrepreneurs` (`entrepreneurs`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0 AUTO_INCREMENT=2204 ;

Code : Tout sélectionner

CREATE TABLE `source_boutique` ( `id` varchar(8) NOT NULL, `nom` varchar(128) NOT NULL, `code` varchar(8) NOT NULL, `adresse` varchar(128) NOT NULL, `ville` varchar(32) NOT NULL, `cp` varchar(10) NOT NULL, `fax` varchar(32) NOT NULL, `type_client` varchar(32) NOT NULL, `maj` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
rspir

ViPHP
ViPHP | 3607 Messages

18 janv. 2009, 23:30

Euh là je pencherais plutôt sur la requête update...
Une requête dans une boucle ça n'est de toute façon pas une solution...
D'ailleurs à quoi celà te sert t'il?
Je ne vois pas pourquoi tu sépares les types de boutiques pour ta requête update,
et dans cette dernière il n' ya rien qui change en fonction des catgéorie... que vaut $a? d'où sort cette variable?
Il y a surement moyen de faire un update sans passer par tes multiples boucles...

Eléphant du PHP | 94 Messages

18 janv. 2009, 23:39

Bonsoir
$a=strtolower($type[$i]); 
ex : Si $type[$i] = Particuliers : Particuliers est la valeurs dans la table source_boutique et particuliers ($a) est le nom du champ dans la table boutique.

Pour ce qui est de l'empilement des boucles. Je suis d'accord. D'autant que je viens de voir que je n'ai pas le résultat escompté.

Ce que je veux c'est que le champ associations soit à 1 dans ma table boutique lorsque qu'il y a un enregistrement avec type_client=Associations dans la table source_boutique (idem pour Particuliers, Professionnels) ....

Je cherche une solution, une idée, un conseil ?

Edit :
J'ai simplifié mon code de la manière suivante.
C'est assez rapide ... est ce que cette requête est "propre" ?
$type = array('Associations','Entrepreneurs','Professionnels','Particuliers');
			
			for ($i=0; $i<4 ; $i++)
			{
				$a=strtolower($type[$i]);
				$rq="UPDATE boutique,source_boutique SET $a='1' WHERE (source_boutique.code=boutique.code AND source_boutique.type_client = '$type[$i]')";
				ExecRequete ($rq, $connexion);
			}
Modifié en dernier par rspir le 19 janv. 2009, 00:37, modifié 1 fois.
rspir

ViPHP
ViPHP | 3607 Messages

19 janv. 2009, 00:15

Déjà quelles sont les structures des tables pdv et source_pdv?
Ensuite, ta requête est un peu mieux, mais je ne vois pas de clause "FROM" dans ton update? est-ce normal?
Sinon je ne sais pas trop si cette requête fait ce que tu veux, car je n'ai pas compris ton but...
Essaye de t'exprimer plus clairement ;)

Eléphant du PHP | 94 Messages

19 janv. 2009, 00:42

Les tables s'appellent boutique et source_ boutique. Elles sont décrites plus haut ...

Ce que je veux faire ?????? :? dans la table source_boutique j'ai, par exemple, 2 enregistrements pour la boutique 1 :

Boutique 1 ...... Professionnels
Boutique 1 ...... Particuliers

Je veux dans la table boutique n'avoir qu'un seul enregistrement pour Boutique 1 avec les champs particulier et professionnels valorisé à 1

Est ce plus clair ????

Pour ce qui est du FROM ... je ne savais pas qu'il fallait une clause FROM pour UPDATE
rspir

ViPHP
ViPHP | 2291 Messages

19 janv. 2009, 09:07

Pour ce qui est du FROM ... je ne savais pas qu'il fallait une clause FROM pour UPDATE
Normal il n'en faut pas :wink:
"FROM" dans ton update?
Pour Update oui :wink:

Cette requête donne quoi ?
"UPDATE source_boutique , boutique
 SET source_boutique sb , boutique bt
 WHERE sb.code = bt.code
 AND sb.type_client = '" . $type[$i] . "'";

ViPHP
ViPHP | 3607 Messages

19 janv. 2009, 10:15

Houlà oui pardon...
j'avais pas vu qu'il y avait les noms de table dans sa requête... :roll:
Scousi moi!