957 votes

Rejoindre la sous-requête

Je suis un utilisateur MySQL old-school et j'ai toujours préféré JOIN sur les sous-requêtes. Mais de nos jours tout le monde utilise des sous-requêtes et je déteste ça, je ne sais pas pourquoi.

Je manque de connaissances théoriques pour juger par moi-même s'il y a une différence. Est-ce qu'une sous-requête vaut un JOIN et donc il n'y a pas de quoi s'inquiéter?

941voto

Marcelo Cantos Points 91211

Les sous-requêtes sont logiquement bonne façon de résoudre les problèmes de la forme, "Obtenir des faits à partir d'Un, à la condition que les faits de la B". Dans de tels cas, il est plus logique de bâton, B une sous-requête que de faire une jointure. Il est également plus sûr, dans un sens pratique, puisque vous n'avez pas à être prudent au sujet de se doubler faits à partir d'Un en raison de plusieurs matchs contre B.

En pratique, cependant, la réponse revient souvent à la performance. Certains optimiseurs de sucer des citrons lors d'une jointure vs une sous-requête, et certains sucer des citrons dans l'autre sens, et c'est l'optimiseur de spécifique, de SGBD spécifique de la version et des requêtes spécifiques.

Historiquement, explicite rejoint généralement de gagner, d'où l'établi de la sagesse que les jointures sont mieux, mais optimiseurs sont de mieux en mieux tout le temps, et donc, je préfère écrire des requêtes d'abord dans une logique de cohérence, puis restructurer si les contraintes de performances justifient.

371voto

Kronass Points 2630

Dans la plupart des cas JOINs sont plus rapides que les sous-requêtes et il est très rare pour une sous-requête pour être plus rapide.

En JOINs SGBDR pouvez créer un plan d'exécution qui est mieux pour votre requête et peut prédire quelles données doivent être chargées de la traiter et de gagner du temps, à la différence de la sous-requête dans laquelle il va exécuter toutes les requêtes et de les charger toutes leurs données pour le traitement.

La bonne chose dans les sous-requêtes, c'est qu'ils sont plus lisibles que d' JOINs: c'est pourquoi la plupart des nouveaux SQL gens préfèrent eux; c'est le moyen le plus facile; mais quand il s'agit de performance, les JOINTURES sont mieux dans la plupart des cas, même si ils ne sont pas difficiles à lire.

137voto

Frank Heikens Points 29270

EXPLAIN permet de voir comment votre base de données exécute la requête sur vos données. Il y a un énorme « ça dépend » dans cette réponse...

PostgreSQL peut réécrire une sous-requête pour une jointure ou une jointure avec une sous-requête quand il pense que l’un est plus rapide que l’autre. Tout dépend des données, corrélation, index, quantité de données, requête, etc..

43voto

Unreason Points 8703

Tout d'abord, pour comparer les deux d'abord, vous devez distinguer les requêtes avec des sous-requêtes:

  1. une classe de sous-requêtes ont toujours équivalent requête écrite avec des jointures
  2. une classe de sous-requêtes qui ne peut pas être réécrite en utilisant les jointures

Pour la première classe de requêtes un bon SGBD va voir les jointures et sous-requêtes, comme l'équivalent, et produisent même des plans de requête.

Ces jours-ci, même mysql.

Pourtant, parfois, il n'est pas, mais cela ne signifie pas que les jointures de toujours gagner - j'ai eu le cas lors de l'utilisation de sous-requêtes mysql amélioration de la performance. (Par exemple, si il ya quelque chose de prévention de mysql planificateur de correctement estimer le coût et si le planificateur de ne pas voir la jointure de la variante et de la sous-requête-variante comme même, alors les sous-requêtes peuvent surpasser les jointures en imposant un certain chemin d'accès).

La Conclusion est que vous devez tester vos requêtes pour les joindre et de sous-requête des variantes si vous voulez être sûr que l'on va faire mieux.

Pour la deuxième classe, la comparaison n'a de sens que ces requêtes ne peut pas être réécrite en utilisant des jointures et dans ces cas, les sous-requêtes sont une façon naturelle de faire les tâches nécessaires et vous ne devriez pas faire de discrimination contre eux.

22voto

Uğur Gümüşhan Points 708

La Documentation MSDN pour SQL Server dit

Beaucoup de Transact-SQL qui contient des sous-requêtes peuvent être alternativement formulé que les jointures. D'autres questions peuvent être posées uniquement avec des sous-requêtes. Dans les instructions Transact-SQL, il n'y a généralement pas de différence de performances entre une déclaration qui comprend une sous-requête et un sémantiquement équivalente à l'ancienne version qui ne fonctionne pas. Cependant, dans certains cas, lorsque vous devez vérifier l'existence, une jointure offre de meilleures performances. Sinon, la requête imbriquée doit être traitée pour chaque résultat de la requête externe pour assurer l'élimination des doublons. Dans de tels cas, une jointure donnera de meilleurs résultats.

donc, si vous besoin de quelque chose comme

select * from t1 where exists select * from t2 where t2.parent=t1.id

essayez d'utiliser se joindre à la place. Dans d'autres cas, il ne fait aucune différence.

Je dis: Création de fonctions de sous-requêtes d'éliminer le problème de cluttter et vous permet de mettre en œuvre une logique supplémentaire pour les sous-requêtes. Donc, je vous recommande de créer des fonctions de sous-requêtes chaque fois que possible.

Le désordre dans le code est un gros problème et de l'industrie a été de travailler sur l'éviter depuis des décennies.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X