PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Elimina utilizzando CTE più lentamente rispetto all'utilizzo della tabella temporanea in Postgres

Il CTE è più lento perché deve essere eseguito inalterato (tramite una scansione CTE).

TFM (sezione 7.8.2) afferma: Le istruzioni di modifica dei dati in WITH vengono eseguite esattamente una volta, e sempre fino al completamento, indipendentemente dal fatto che la query primaria legga tutto (o addirittura uno qualsiasi) del loro output. Notare che questo è diverso dalla regola per SELECT in WITH:come affermato nella sezione precedente, l'esecuzione di un SELECT è portato solo nella misura in cui la query primaria richiede il suo output.

Si tratta quindi di una barriera di ottimizzazione; per l'ottimizzatore, lo smantellamento del CTE non è consentito, anche se si tradurrebbe in un piano più intelligente con gli stessi risultati.

Tuttavia, la soluzione CTE può essere rifattorizzato in una sottoquery unita (simile alla tabella temporanea nella domanda). In postgres, una sottoquery unita è solitamente più veloce della variante EXISTS(), al giorno d'oggi.

DELETE FROM customer del
USING ( SELECT id
        , row_number() over(partition by uuid order by created_date desc)
                 as rn
        FROM customer
        ) sub
WHERE sub.id = del.id
AND sub.rn > 1
        ;

Un altro modo è usare un TEMP VIEW . Questo è sintatticamente equivalente alla temp table caso, ma semanticamente equivalente al modulo di sottoquery unito (restituiscono esattamente lo stesso piano di interrogazione, almeno in questo caso). Questo perché l'ottimizzatore di Postgres smantella la vista e la combina con la query principale (pull-up ). Potresti vedere una view come una specie di macro in PG.

CREATE TEMP VIEW targets
AS SELECT id
        , row_number() over(partition by uuid ORDER BY created_date DESC) AS rn
FROM customer;

EXPLAIN
DELETE FROM customer
WHERE id IN ( SELECT id
            FROM targets
            WHERE rn > 1
        );

[AGGIORNATO:mi sbagliavo sul fatto che i CTE debbano essere sempre eseguiti fino al completamento, che è solo il caso dei CTE che modificano i dati]