sql >> Base de Datos >  >> RDS >> PostgreSQL

Eliminar usando CTE más lento que usando la tabla temporal en Postgres

El CTE es más lento porque debe ejecutarse sin cambios (a través de un escaneo CTE).

TFM (sección 7.8.2) establece: Se ejecutan instrucciones de modificación de datos en WITH exactamente una vez, y siempre hasta el final, independientemente de si la consulta principal lee todos (o algunos) de su salida. Tenga en cuenta que esto es diferente de la regla para SELECCIONAR en CON:como se indicó en la sección anterior, la ejecución de un SELECT es llevado sólo en la medida en que la consulta principal exige su resultado.

Por lo tanto, es una barrera de optimización; para el optimizador, no está permitido desmantelar el CTE, incluso si resultaría en un plan más inteligente con los mismos resultados.

Sin embargo, la solución CTE se puede refactorizar en una subconsulta unida (similar a la tabla temporal en la pregunta). En Postgres, una subconsulta unida suele ser más rápida que la variante EXISTS(), hoy en día.

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
        ;

Otra forma es usar una TEMP VIEW . Esto es sintácticamente equivalente a la temp table caso, pero semánticamente equivalente al formulario de subconsulta unida (producen exactamente el mismo plan de consulta, al menos en este caso). Esto se debe a que el optimizador de Postgres desmantela la vista y la combina con la consulta principal (pull-up ). Podrías ver una view como una especie de macro en 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
        );

[ACTUALIZADO:Me equivoqué acerca de que los CTE deben ejecutarse siempre hasta su finalización, que es solo el caso de CTE de modificación de datos]