Je travaille sur la réécriture de certaines requêtes SQL mal écrites et elles utilisent trop les sous-requêtes. Je recherche les meilleures pratiques concernant l'utilisation des sous-requêtes.
Toute aide serait appréciée.
Les sous-requêtes sont généralement correctes sauf si elles sont sous-requêtes dépendantes (également appelées sous-requêtes corrélées ). Si vous utilisez uniquement des sous-requêtes indépendantes et qu'elles utilisent des index appropriés, elles doivent s'exécuter rapidement. Si vous avez une sous-requête dépendante, vous pouvez rencontrer des problèmes de performances car une sous-requête dépendante doit généralement être exécutée une fois pour chaque ligne de la requête externe. Donc, si votre requête externe a 1000 lignes, la sous-requête sera exécutée 1000 fois. D'un autre côté, une sous-requête indépendante ne doit généralement être évaluée 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 de base - si vous pouvez prendre la sous-requête, la supprimer de son contexte, l'exécuter et obtenir un jeu de résultats, c'est un independent subquery
.
Si vous obtenez une erreur de syntaxe car elle fait référence à certaines tables en dehors de la sous-requête, alors c'est un dependent subquery
.
La règle générale comporte bien sûr quelques exceptions. Par exemple:
Si les performances sont un problème, mesurez vos requêtes spécifiques et voyez ce qui vous convient le mieux.
Il n'y a pas de solution miracle ici. Chaque utilisation doit être évaluée de manière indépendante. Il y a des cas où les sous-requêtes corrélées sont tout simplement inefficaces, celle-ci ci-dessous est mieux écrite en tant que 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 NOT EXISTS l'emporteront sur JOINs.
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 tout schéma particulier et distribution de données.
Malheureusement, la réponse dépend grandement du serveur SQL que vous utilisez. En théorie, les jointures sont meilleures du point de vue de la théorie relationnelle pure. Ils laissent le serveur faire ce qu'il faut sous le capot et leur donne plus de contrôle et donc au final peut être plus rapide. Si le serveur est bien implémenté. En pratique, certains serveurs SQL fonctionnent mieux si vous l'incitez à optimiser leurs requêtes via des sous-requêtes et autres.