Quand utiliser les sous-requêtes SQL versus une jointure standard?

je travaille sur la réécriture de certaines requêtes SQL mal écrites et ils utilisent trop les sous-requêtes. Je suis à la recherche de pratiques exemplaires concernant l'utilisation de sous-requêtes.

Toute aide serait appréciée.

29
demandé sur Brad Krusemark 2011-01-26 02:00:11

3 réponses

les sous-séries sont généralement bien sauf si elles sont sous-séries dépendantes ( sous-séries corrélées). Si vous utilisez uniquement des sous-séries indépendantes et qu'elles utilisent des index appropriés, elles doivent être exécutées rapidement. Si vous avez une sous-requête dépendante, vous pourriez rencontrer des problèmes de performance parce qu'une sous-requête dépendante doit typiquement être exécutée une fois pour chaque ligne de la requête externe. Donc si votre requête externe a 1000 lignes, le sous-jeu sera lancé 1000 temps. D'autre part, un sous-produit indépendant ne doit généralement être évalué qu'une seule fois.

si vous n'êtes pas sûr de ce que signifie une sous - requête dépendante ou indépendante voici une règle empirique-si vous pouvez prendre la sous-requête, l'enlever de son contexte, l'exécuter, et obtenir un jeu de résultats alors c'est un independent subquery.

si vous obtenez une erreur de syntaxe parce qu'elle se réfère à certaines tables en dehors de la sous-requête alors son a dependent subquery.

la règle générale a bien sûr quelques exception. Par exemple:

  • de nombreux optimiseurs peuvent prendre une sous-commande dépendante et trouver un moyen de l'exécuter efficacement en tant que jointure. Par exemple, une requête non existante pourrait donner lieu à un plan de requête anti JOIN, de sorte qu'elle ne sera pas nécessairement plus lente que l'écriture de la requête avec une JOIN.
  • MySQL a un bug lorsqu'une sous-requête indépendante à l'intérieur d'une expression IN est incorrectement identifiée comme une sous-requête dépendante et qu'un plan de requête sous-optimal est utilisé. C'est apparemment fixé dans les versions les plus récentes de MySQL.

si la performance est un problème, mesurez vos requêtes spécifiques et voyez ce qui fonctionne le mieux pour vous.

44
répondu Mark Byers 2011-09-20 18:56:32

il n'y a pas de balle en argent ici. Chaque utilisation doit être évalué de façon indépendante. Il y a des cas où les sous-séries corrélées sont totalement inefficaces, celle ci-dessous est mieux écrite comme une JOIN

select nickname, (select top 1 votedate from votes where user_id=u.id order by 1 desc)
from users u

D'un autre côté, les requêtes EXISTS et non EXISTS l'emporteront sur les jointures.

select ...
where NOT EXISTS (.....)

Est normalement plus rapide que

select ...
FROM A LEFT JOIN B
where B.ID is null

pourtant, même ces généralisations peuvent être fausses pour n'importe quel schéma particulier et la distribution de données.

6
répondu RichardTheKiwi 2011-01-25 23:07:02

malheureusement, la réponse dépend beaucoup du serveur sql que vous utilisez. En théorie, les jointures sont meilleures d'un point de vue purement relationnel. Ils laissent le serveur faire la bonne chose sous le capot et leur donne plus de contrôle et donc à la fin peut être plus rapide. Si le serveur est bien implémenté. En pratique, certains serveurs SQL fonctionnent mieux si vous le piégez en optimisant ses requêtes via des sous-requêtes et autres.

4
répondu Wes Hardaker 2011-01-25 23:02:44