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

La mejor manera de eliminar millones de filas por ID

Todo depende...

  • Suponiendo que no hay acceso de escritura simultáneo a las mesas involucradas o puede que tenga que bloquear las mesas exclusivamente o esta ruta puede no ser para usted en absoluto.

  • Elimine todos los índices (posiblemente excepto los necesarios para la eliminación en sí).
    Recréelos después. Eso suele ser mucho más rápido que las actualizaciones incrementales de los índices.

  • Compruebe si tiene activadores que se puedan eliminar o desactivar temporalmente de forma segura.

  • ¿Las claves externas hacen referencia a su tabla? ¿Se pueden eliminar? ¿Eliminado temporalmente?

  • Según la configuración de vacío automático, puede ayuda para ejecutar VACUUM ANALYZE antes de la operación.

  • Algunos de los puntos enumerados en el capítulo relacionado del manual Poblando una base de datos también puede ser útil, dependiendo de su configuración.

  • Si elimina grandes porciones de la tabla y el resto cabe en la RAM, la forma más rápida y sencilla puede ser esta:

BEGIN; -- typically faster and safer wrapped in a single transaction

SET LOCAL temp_buffers = '1000MB'; -- enough to hold the temp table

CREATE TEMP TABLE tmp AS
SELECT t.*
FROM   tbl t
LEFT   JOIN del_list d USING (id)
WHERE  d.id IS NULL;      -- copy surviving rows into temporary table

TRUNCATE tbl;             -- empty table - truncate is very fast for big tables

INSERT INTO tbl
SELECT * FROM tmp;        -- insert back surviving rows.
-- ORDER BY ?             -- optionally order favorably while being at it

COMMIT;

De esta manera, no tiene que volver a crear vistas, claves externas u otros objetos dependientes. Y obtienes una mesa impecable (clasificada) sin hinchazón.

Lea acerca de los temp_buffers ajuste en el manual. Este método es rápido siempre que la tabla quepa en la memoria, o al menos en su mayor parte. El contenedor de transacciones lo protege contra la pérdida de datos si su servidor falla en medio de esta operación.

Ejecute VACUUM ANALYZE después. O VACUUM FULL ANALYZE si desea llevarlo al tamaño mínimo (toma bloqueo exclusivo). Para tablas grandes considere las alternativas CLUSTER / pg_repack o similar:

  • Optimizar el rango de consulta de marca de tiempo de Postgres

Para tablas pequeñas, un simple DELETE en lugar de TRUNCATE suele ser más rápido:

DELETE FROM tbl t
USING  del_list d
WHERE  t.id = d.id;

Leer las Notas sección para TRUNCATE en el manual En particular (como también señaló Pedro en su comentario):

TRUNCATE no se puede usar en una tabla que tiene referencias de clave externa de otras tablas, a menos que todas esas tablas también se trunquen en el mismo comando. [...]

Y:

TRUNCATE no disparará ningún ON DELETE activadores que pueden existir para las tablas.