Jointure de plusieurs tables qui rend le site

Résolu/Fermé
rambad Messages postés 8 Date d'inscription lundi 26 novembre 2007 Statut Membre Dernière intervention 3 novembre 2009 - 2 sept. 2009 à 12:27
rambad Messages postés 8 Date d'inscription lundi 26 novembre 2007 Statut Membre Dernière intervention 3 novembre 2009 - 4 sept. 2009 à 12:18
Bonjour,
J’ai une requête qui fait joindre 14 table pour une recherche dans mon site a l’exécution tout le site devient lourd même pour l’autre utilisateur du site si vous avez une solution pour mon problème je serais ravis et merci d’avance

6 réponses

M@dien Messages postés 437 Date d'inscription mercredi 29 juillet 2009 Statut Membre Dernière intervention 23 septembre 2010 74
3 sept. 2009 à 16:17
OK donc pour with(nolock) on va laisser tomber, ça marche pas via phpMyAdmin apparemment.

Pour le SELECT, je pense que au lieu de ça:
	INNER JOIN ( 	SELECT * 
					FROM Table5 l 
						INNER JOIN Table6 v 
							ON l.localisation_ville_id = v.villes_id ) lv 
		ON lv.annonces_id = a.annonces_id 
		AND lv.localisation_region_id = 1 
		AND lv.localisation_departement_id = 1 
		AND ( 	lv.villes_name LIKE '%L\'Abergement Clémenciat%' 
				OR lv.ville_zipcode LIKE '%01400%' ) 

tu pourrais mettre ça:
			INNER JOIN  Table5 l 
			ON l.annonces_id = a.annonces_id 
		INNER JOIN Table6 v 
			ON l.localisation_ville_id = v.villes_id
			AND v.localisation_region_id = 1 
			AND v.localisation_departement_id = 1 
			AND ( 	v.villes_name LIKE '%L\'Abergement Clémenciat%' 
					OR v.ville_zipcode LIKE '%01400%' ) 



Comme je l'ai dit plus haut, ne connaissant pas tes tables, je ne suis pas sûr de ce que je propose.
1
M@dien Messages postés 437 Date d'inscription mercredi 29 juillet 2009 Statut Membre Dernière intervention 23 septembre 2010 74
2 sept. 2009 à 14:31
Bonjour,

Est-ce que la jointure sur 14 tables est nécessaire?
Il est parfois plus rapide de passer par des tables temporaires que de faire une requête en "one shot".

Sinon, pour le problème de lenteur, c'est évidemment du au nombre de jointures.

Et ça ralentira aussi les autres utilisateurs, car le serveur va devoir prendre pas mal de ressources pour ta requête.
Cependant, essaye de finir ta requête avec " WITH (nolock)", qui permet d'éviter de vérouiller les tables lors du SELECT, ce qui permettra aux autres utilisateurs d'accéder à la base avec un peu plus de facilité.
0
rambad Messages postés 8 Date d'inscription lundi 26 novembre 2007 Statut Membre Dernière intervention 3 novembre 2009
3 sept. 2009 à 11:55
Bonjour,
Merci pour votre réponse, la requête sert à faire une recherche avec plusieurs critère de recherche ,

pour WITH (nolock) comment je peut l'utiliser ou je peut la mettre exactement dans la requette et en voici la requette:

SELECT * FROM Table1 a INNER JOIN Table2 t ON a.annonces_type_transaction_id = t.transactions_id AND t.transactions_name = '' INNER JOIN Table3 m ON a.membres_id = m.membres_id INNER JOIN Table4 b ON a.annonces_type_bien_id = b.biens_id AND biens_name = '' INNER JOIN ( SELECT * FROM Table5 l INNER JOIN Table6 v ON l.localisation_ville_id = v.villes_id ) lv ON lv.annonces_id = a.annonces_id INNER JOIN Table7 l ON l.annonces_id = a.annonces_id INNER JOIN Table8 c ON c.annonces_id = a.annonces_id INNER JOIN Table9 ON ie.annonces_id = a.annonces_id INNER JOIN Table10 tr ON tr.annonces_id = a.annonces_id INNER JOIN Table11_financiere cf ON cf.annonces_id = a.annonces_id INNER JOIN Table12 dd ON dd.annonces_id = a.annonces_id INNER JOIN Table13 lp ON lp.annonces_id = a.annonces_id WHERE 1 AND lv.localisation_region_id = 1 AND lv.localisation_departement_id = 1 AND ( lv.villes_name LIKE '%L\'Abergement Clémenciat%' OR lv.ville_zipcode LIKE '%01400%' ) AND a.annonces_disponibilite LIKE '%%' AND ie.interieur_exterieur_etage = '' AND ie.interieur_exterieur_nb_niveau = ' ' AND ie.interieur_exterieur_nb_niveau LIKE '% %' AND ie.interieur_exterieur_date_construction LIKE '%%' AND annonces_validation = 1 AND annonces_publication = 1 AND TO_DAYS(NOW()) - TO_DAYS(annonces_date_expiration) <= 0 GROUP BY a.annonces_id


0
M@dien Messages postés 437 Date d'inscription mercredi 29 juillet 2009 Statut Membre Dernière intervention 23 septembre 2010 74
3 sept. 2009 à 12:28
OK, un sacré bazar ta requête =)

Vu que tu as caché les noms des tables je ne peux pas vraiment t'optimiser ça, mais j'ai des conseils:

1- Le SELECT * est groumand. à chaque jointure il ajoute des colonnes et on se retrouve avec un résultat à 124 colonnes.... afficher seulement les colonnes utiles va accélérer le traitement et libérer un peu de mémoire.
2- Evite A TOUT PRIX le SELECT à l'intérieur de ta requête. revoit ta méthode, un INNER JOIN bien placé devrait aller je pense, il faut seulement trouver comment. mais les sous-requêtes sont un GROUFFRE à ressources.
3- La clause WHERE peut être inutile, en déplaçant les conditions dans les jointures, comme suit:
SELECT * 
FROM Table1 a 
	INNER JOIN Table2 t 
		ON a.annonces_type_transaction_id = t.transactions_id 
		AND a.annonces_disponibilite LIKE '%%' 
		AND t.transactions_name = '' 
	INNER JOIN Table3 m 
		ON a.membres_id = m.membres_id 
	INNER JOIN Table4 b 
		ON a.annonces_type_bien_id = b.biens_id 
		AND biens_name = '' 
	INNER JOIN ( 	SELECT * 
					FROM Table5 l 
						INNER JOIN Table6 v 
							ON l.localisation_ville_id = v.villes_id ) lv 
		ON lv.annonces_id = a.annonces_id 
		AND lv.localisation_region_id = 1 
		AND lv.localisation_departement_id = 1 
		AND ( 	lv.villes_name LIKE '%L\'Abergement Clémenciat%' 
				OR lv.ville_zipcode LIKE '%01400%' ) 
	INNER JOIN Table7 l 
		ON l.annonces_id = a.annonces_id 
	INNER JOIN Table8 c 
		ON c.annonces_id = a.annonces_id 
	INNER JOIN Table9 
		ON ie.annonces_id = a.annonces_id 
		AND ie.interieur_exterieur_etage = '' 
		AND ie.interieur_exterieur_nb_niveau = ' ' 
		AND ie.interieur_exterieur_nb_niveau LIKE '% %' 
		AND ie.interieur_exterieur_date_construction LIKE '%%' 
	INNER JOIN Table10 tr 
		ON tr.annonces_id = a.annonces_id 
	INNER JOIN Table11_financiere cf 
		ON cf.annonces_id = a.annonces_id 
	INNER JOIN Table12 dd 
		ON dd.annonces_id = a.annonces_id 
	INNER JOIN Table13 lp 
		ON lp.annonces_id = a.annonces_id 
WHERE 1 
	AND annonces_validation = 1 
	AND annonces_publication = 1 
	AND TO_DAYS(NOW()) - TO_DAYS(annonces_date_expiration) <= 0 
GROUP BY a.annonces_id
WITH (NOLOCK)

Je n'ai pas déplacé les 3 dernières conditions car je ne sais pas où les placer vu que tu as changé les noms, mais il faut les déplacer comme les autres.
L'avantage de faire comme ça est de filtrer au plus tôt, au moment de la jointure. cela limite fortement le nombre de lignes de la table de résultat.
Si on laisse tout dans le where, la table créée est énorme avant d'être filtrée.

4- Je ne suis pas sûr comme je ne connais pas bien ton modèle de données, mais faire un select * couplé avec un group by n'est pas utile, ça va tout retourner sauf les doublons. le GROUP BY est groumand et si on n'utilise pas de count() ou sum() ou une fonction qui nécessite un group by, c'est une perte de ressources. fait un SELECT DISTINCT * si tu veux seulement supprimer des doublons.
5- J'ai ajouté le WITH (NOLOCK) à la fin de la requête.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
rambad Messages postés 8 Date d'inscription lundi 26 novembre 2007 Statut Membre Dernière intervention 3 novembre 2009
3 sept. 2009 à 14:06
merci pour la réponse ,
j'ai commencer par mettre le WITH (NOLOCK) à la fin de la requête et ça me donne cette erreur sql :

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(NOLOCK) LIMIT 0, 30' at line 1

1- ce qui concerne la première instruction je vais changer le "SELECT *" par les champs nécessaire en sachant que presque tout les champs sont nécessaire .
2- ce qui concerne le SELECT à l'intérieur de ta requête j'ai pas trouver d'autre solution la table 6 n'a de liaison qu'avec la table 5 si t'a une solution je serai ravie.
3- je vais déplacer les conditions dans les jointures, et les 3 dernières conditions appartienne a la table 1.
4- concernant le le GROUP BY je l'ai ajouter parce qu'il m'affiche la même résultat plusieurs fois .
encore une fois merci pour ta reponse
0
rambad Messages postés 8 Date d'inscription lundi 26 novembre 2007 Statut Membre Dernière intervention 3 novembre 2009
4 sept. 2009 à 12:18
merci pour ton assistance j'ai suivie tes instruction et ça marche
0