[php/mysql] optimisation possible? - peut on diminuer le nb de requetes?

En gros, tu fais un joli produit cartésien de A et de B UNION /dev/null.

Si c’est pas plus clair ça :o

mais ds quel cas j’utilise LEFT JOIN ou RIGHT JOIN? et INNER JOIN?

Pcq ds ton cas, si je dois faire 3 (ou plus) test d’égalité, cmt je fais?

Avec mon “bete” système, je rajoute des AND… et c’est tout simple. Mais toi?

Genre, une requete comme ca, deviendra quoi?

SELECT *
FROM 
ta A, 
tb B,
tc c
WHERE A.`id` = B.`album` 
AND B.`membre` = 'XXX'
AND C.`id`= A.`cat` 
ORDER BY A.`cat` ASC, A.`album` ASC
");

j’ai donc:

  • l’id de ma table A (album) qui vaut l’id de l’album stocké ds ma table B
  • le membre (stocké dans B) qui vaut une XXX (cst)
  • l’id de C (catégorie) qui vaut l’id de la catégorie stocké ds A

en outre, mes tables sont réalisées comme suit:
A: id, cat, titre // album
B: id, alb, titre // contenu
C: id, titre // categorie

dans l’ordre j’ai donc catégorie > album > contenu

Tout ca pour dire que… cette requete je ne vois pas cmt la faire (en réalité, celle là ou une autre, c’est égal, du moment qu’elle a trois argument ou plus, et cela sur trois tables différentes.

En général c’est toujours INNER JOIN, sauf si tu peux avoir un champ NULL dans l’une ou l’autre des tables. Si c’est la table de gauche (dans le FROM typiquement), c’est LEFT, si c’est celle de droite c’est RIGHT.

Il faut aussi schématiser ta bdd :slight_smile: et représenter les relations entre les tables. Là t’auras ton JOIN qui en général se fait par identifiant (les ‘id’)

merci, mais ca ne résoud pas mon principal soucis: cmt faire qd j’ai trois table en jeux? :frowning:

from t1 lef join t2 on <condition> left join t3 on <condition>

si je suis ton système, je fais

SELECT *
FROM
ta A LEFT JOIN tb B ON A.`id` = B.`album` LEFT JOIN tc c ON  C.`id`= A.`cat`
WHERE B.`membre` = 'XXX' 
ORDER BY A.`cat` ASC, A.`album` ASC
");

et ca me fait exactement la meme chose que la requete ci-dessus… Je sais pas si c’est à ca que tu pensais. Mais en tk ca marche. Cepandant, excepté si ca bouffe moins de ressource, je ne vois absolument pas l’interet de ce genre de chose :S En quoi est-ce “plus clair”?

edit: après verification, correction, le système “caca” (ma requete précédente) s’execute 2 fois plus vite que la requete ci-dessus…

L’avantage des JOIN c’est d’éviter justement de foutre ça dans le WHERE. C’est plus lisible par la suite (imagines que tu veuilles rechercher de manière plus conséquentes?)

Tu as essayé un EXPLAIN avec ou sans le JOIN?

m’etonnerai que le explain soit vraiment different…
il se basera sur les meme index (ceux des table left joiné)
il ira un poil plus vite parce qu’il va utiliser un index de moin (celui de la table principal qu’il parcours en entier)

explain: requete JOIN

table type possible_keys key key_len ref rows Extra
a ALL NULL NULL NULL NULL 28 Using temporary; Using filesort
p ALL NULL NULL NULL NULL 610 where used
c eq_ref id id 1 a.categorie 1

exlain: requete WHERE

table type possible_keys key key_len ref rows Extra
p ALL NULL NULL NULL NULL 610 where used; Using temporary; Using filesort
a eq_ref id id 2 p.album 1 where used
c eq_ref id id 1 a.categorie 1

pour le reste, c’est plus simple à relire ensuite, mais l’execution est plus rapide avec les WHERE… Alors que faire? Ce que je dois favoriser, c’est avant tout une execution rapide et l’utilisation du moins de ressource possible…

610 contre 638 c pareil

ps : c du CBO mysql ou du RBO ?

Ce message n’était pas conforme aux règles d’utilisation du nouveau forum :

CBO? RBO?

euh… kesako CBO ou RBO? :smiley:

bah pratiquement pareil, moi je te dis qu’à l’execution, sur 25 reload de la page, je passe d’une moyenne de 0.02s à 0.04s… Tu vas me dire que c’est pas très long, mais ca reste du simple au double…

RBO = rule based optimisation (historiquement le premier)
CBO = cost based optimisation (l’optimisation devient tellement compliqué qu on se base sur des regle statistiques de cout plutot que sur des regle fixe)

bizar sur 25 reload ru devrait gagner 0.02*(638-610)/638 secondes :slight_smile:

je sais pas du tout de quel type il s’agit (si tu me dis où trouver l’info…)

sinon, j’ai refais l’essais et je te confirme mes dire, pour préciser, il s’agit de 0.019 et de 0.038s…

comme koi le explain donne pas toutes les infos …

ben sur le site de mysql… pour la reponse

ca m’e**rde cette histoire que ca soit plus long à charger… Et moi qui voulais apprendre à coder proprement :stuck_out_tongue:

il me reste plus qu’à intégrer l’histoire de GROUP BY dont tu m’avais parlé au début… je fais un essai tout à l’heure et je reviens à la charge si je patauge (vu les docs que vous m’avez donné, ca devrais pouvoir se faire… euh… esperons :ane: )

en réalité, je suis oqp de lire depuis tout à l’heure le liens que tu m’as donné, et il n’y a rien à faire, cette histoire de jointure me parait totalement abstrait.

Je ne comprend absolument pas la différence entre une jointure et un “filtre d’élimination” (clause where).

Pour moi, l’un et l’autre ont le meme role, restreindre les résultats selon un certain nombre de condition. Alors, certe, le join est sencé etre plus clair/lisible (je dis sencé pcq pour moi ca me parait très obscure cet histoire de left join, right join,join…).

Y a-t-il un de vous qui pourrait m’expliquer ca de manière explicite…

(désolé de vous ennuyer avec ca, mais j’ai beau lire et relire, je ne comprend réellement pas… :S)

Ben…

Dans une des tables jointes, essaye créer un enregistrement avec des données faussées, qui n’existe pas. Par exemple, pour l’identifiant de b, tu mets 0 pour la table a.

Essaye de retrouver cette donnée (qui peut être valide : pas de catégorie, etc) avec ta requête avec WHERE, et essayes avec un LEFT JOIN.

pardon? vous disiez ? :??:

grumpf.

Prend deux tables jointes par la clef join_id

ta requête sera :

SELECT *
FROM a, b
WHERE a.join_id = b.join_id

Bon, essaye de mettre comme valeur de join_id pour un enregistrement de la table a une valeur débile comme 0 (ne doit pas être présent dans b)

Ta requête ne raménera pas ton enregistrement.

Avec un LEFT JOIN :

SELECT *
FROM a
LEFT JOIN b ON a.join_id = b.join_id

Paf : tu as retrouvé ton enregistrement!

Voilà une (grosse) différence.