par
caroube » 17 juil. 2008, 10:51
La clause WHERE pour faire des jointures n'est plus recommandée pour les SGBD actuels car moins performante que JOIN.
L'idée de base du SQL et des langages déclaratifs, c'est de permettre au développeur de dire ce qu'il veut obtenir comme résultat sans se préoccuper de savoir comment le SGBD va faire pour atteindre le résultat (contrairement aux langages procéduraux classiques où le développeur décrit la manière d'obtenir le résultat : l'algorithme). Ce serait donc une régression que les développeurs soient maintenant obligés de se dire "il faut que j'utilise JOIN plutôt que WHERE" car le moteur d'optimisation des requêtes du SGBD ne remplit pas son rôle.
Ensuite, mettre dans le même sac tous les SBGD "actuels" qui seraient tous plus performants avec JOIN qu'avec WHERE me semble étrange : chacun d'entre eux a, que je sache, un moteur d'optimisation des requêtes entièrement différent. Il n'y a donc aucune raison que tous les développeurs de SGBD aient décidé, en même temps, de privilégier les JOIN par rapport aux WHERE.
D'autant plus que par exemple, Oracle utilise une syntaxe très spécifique (et à mon avis beaucoup plus lisible, mais ce n'est pas le sujet) qui permet de faire des jointures externes directement dans la clause WHERE.
Enfin, la documentation MySQL n'est pas vraiment explicite sur le gain de performances de JOIN sur WHERE. Au contraire, on y lit à la page
Comment MySQL optimise les clauses LEFT JOIN et RIGHT JOIN
Toutes les conditions du LEFT JOIN sont transmises à la clause WHERE.
ou encore
Depuis la version 4.0.14, MySQL effectue l'optimisation LEFT JOIN suivante : si la condition WHERE est toujours fausse pour la ligne NULL générée, la jointure LEFT JOIN est transformée en jointure normale.
Par exemple, dans la requête suivante, la clause WHERE sera fausse si t2.column est NULL : il est donc valide de convertir la jointure en une jointure normale.
Code : Tout sélectionner
SELECT * FROM t1 LEFT JOIN t2 ON (column1) WHERE t2.column2=5;
Par conséquent, il est possible de convertir la requête en jointure normale :
Code : Tout sélectionner
SELECT * FROM t1,t2 WHERE t2.column2=5 AND t1.column1=t2.column1;
Cela peut se faire plus rapidement, car MySQL peut maintenant utiliser la table t2 avant la table t1 si les relations sont plus favorables.
[quote]La clause WHERE pour faire des jointures n'est plus recommandée pour les SGBD actuels car moins performante que JOIN. [/quote]
L'idée de base du SQL et des langages déclaratifs, c'est de permettre au développeur de dire ce qu'il veut obtenir comme résultat sans se préoccuper de savoir comment le SGBD va faire pour atteindre le résultat (contrairement aux langages procéduraux classiques où le développeur décrit la manière d'obtenir le résultat : l'algorithme). Ce serait donc une régression que les développeurs soient maintenant obligés de se dire "il faut que j'utilise JOIN plutôt que WHERE" car le moteur d'optimisation des requêtes du SGBD ne remplit pas son rôle.
Ensuite, mettre dans le même sac tous les SBGD "actuels" qui seraient tous plus performants avec JOIN qu'avec WHERE me semble étrange : chacun d'entre eux a, que je sache, un moteur d'optimisation des requêtes entièrement différent. Il n'y a donc aucune raison que tous les développeurs de SGBD aient décidé, en même temps, de privilégier les JOIN par rapport aux WHERE.
D'autant plus que par exemple, Oracle utilise une syntaxe très spécifique (et à mon avis beaucoup plus lisible, mais ce n'est pas le sujet) qui permet de faire des jointures externes directement dans la clause WHERE.
Enfin, la documentation MySQL n'est pas vraiment explicite sur le gain de performances de JOIN sur WHERE. Au contraire, on y lit à la page [url=http://dev.mysql.com/doc/refman/5.0/fr/left-join-optimization.html]Comment MySQL optimise les clauses LEFT JOIN et RIGHT JOIN[/url]
[quote]
Toutes les conditions du LEFT JOIN sont transmises à la clause WHERE.
[/quote]
ou encore
[quote]
Depuis la version 4.0.14, MySQL effectue l'optimisation LEFT JOIN suivante : si la condition WHERE est toujours fausse pour la ligne NULL générée, la jointure LEFT JOIN est transformée en jointure normale.
Par exemple, dans la requête suivante, la clause WHERE sera fausse si t2.column est NULL : il est donc valide de convertir la jointure en une jointure normale.
[code]SELECT * FROM t1 LEFT JOIN t2 ON (column1) WHERE t2.column2=5;[/code]
Par conséquent, il est possible de convertir la requête en jointure normale :
[code]SELECT * FROM t1,t2 WHERE t2.column2=5 AND t1.column1=t2.column1;[/code]
Cela peut se faire plus rapidement, car MySQL peut maintenant utiliser la table t2 avant la table t1 si les relations sont plus favorables.
[/quote]