J'ai une table subscription
et une table payments
que j'ai besoin de joindre. J'essaie de choisir entre deux options et la performance est une considération clé.Dois-je mettre un filtre de numéro de ligne en condition de jointure ou dans un CTE antérieur?
Laquelle des deux OPTIONS ci-dessous fonctionnera le mieux?
J'utilise Impala, et ces tables sont grandes (plusieurs millions de lignes) Je suis besoin de seulement obtenir une ligne pour chaque id
et date
de groupement (donc la fonction analytique row_number()
).
J'ai raccourci les requêtes pour illustrer ma question:
OPTION 1:
WITH cte
AS (
SELECT *
, SUM(amount) OVER (PARTITION BY id, date)
AS sameday_total
, ROW_NUMBER() OVER (PARTITION BY id, date ORDER BY purchase_number DESC)
AS sameday_rownum
FROM payments
),
payment
AS (
SELECT *
FROM cte
WHERE sameday_rownum = 1
)
SELECT s.*
, p.sameday_total
FROM subscription
INNER JOIN payment ON s.id = p.id
OPTION 2:
WITH payment
AS (
SELECT *
, SUM(payment_amount) OVER (PARTITION BY id, date)
AS sameday_total
, ROW_NUMBER() OVER (PARTITION BY id, date ORDER BY purchase_number DESC)
AS sameday_rownum
FROM payments
)
SELECT s.*
, p.sameday_total
FROM subscription
INNER JOIN payment ON s.id = p.id
AND p.sameday_rownum = 1
Mettez simplement la condition dans la clause 'on'. Pas besoin d'encombrer la requête avec deux CTE. –
Merci. Donc, aucun impact sur les performances de toute façon, étant donné que c'est une jointure interne? Je me demandais si cela est similaire à la performance du filtrage des conditions de jointure par rapport au filtrage des clauses where dans le prédicat sql de l'instruction SQL finale? – cdabel
Vous devriez être capable de dire en regardant le plan de requête pour voir si l'optimiseur va appliquer le filtre au début ou à la fin. – Connor