Comme pour toute requête, la méthode la plus efficace est "ça dépend". De nombreuses variables sont en jeu :le nombre de lignes dans les tables, la longueur des lignes, l'existence d'index, la RAM sur le serveur, etc.
La meilleure façon de gérer ce type de problème (en pensant à la maintenabilité et à une approche globale de l'efficacité) consiste à utiliser les CTE, qui vous permettent de créer un résultat temporaire et de le réutiliser tout au long de votre requête. Les CTE utilisent le mot-clé WITH, et alias essentiellement un résultat en tant que table, de sorte que vous pouvez vous JOINDRE plusieurs fois :
WITH user_memberships AS (
SELECT *
FROM memberships
WHERE user_id = ${id}
), user_apps AS (
SELECT *
FROM apps
INNER JOIN user_memberships
ON user_memberships.team_id = apps.team_id
), user_collections AS (
SELECT *
FROM collections
INNER JOIN user_memberships
ON user_memberships.team_id = collections.team_id
), user_webhooks AS (
SELECT *
FROM webhooks
LEFT OUTER JOIN user_collections ON user_collections.id = webhooks.collection_id
INNER JOIN user_memberships
ON user_memberships.team_id = webhooks.team_id
OR user_memberships.team_id = user_collections.team_id
)
SELECT events.*
FROM events
WHERE app_id IN (SELECT id FROM user_apps)
OR collection_id IN (SELECT id FROM user_collections)
OR membership_id IN (SELECT id FROM user_memberships)
OR team_id IN (SELECT team_id FROM user_memberships)
OR user_id = ${id}
OR webhook_id IN (SELECT id FROM user_webhooks)
;
Les avantages de procéder ainsi sont :
- Chaque CTE peut tirer parti d'un index sur les prédicats JOIN appropriés et renvoyer les résultats pour ce sous-ensemble plus rapidement, plutôt que de laisser le planificateur d'exécution tenter de résoudre une série de prédicats complexes
- Les CTE peuvent être gérés individuellement, ce qui facilite la résolution des problèmes de sous-ensembles
- Vous n'enfreignez pas le principe DRY
- Si le CTE a une valeur en dehors de la requête, vous pouvez le déplacer dans une procédure stockée et la référencer à la place