Cómo insert a granel solo nuevas filas en PostreSQL

Tengo una list de productos (3 millones de artículos) sin identificación, solo títulos. Pero no sé qué títulos ya existen en DB. Se deben agregar nuevos productos (alnetworkingedor de 2,9 millones de elementos) a DB. Después de eso, debo saber la identificación de cada producto (nuevo y existente).

¿Existe la forma más rápida de hacerlo en PostgreSQL? Puedo cambiar la database según sea necesario (agregar valores pnetworkingeterminados, agregar columnas, etc.).

Datos de importacion

COPY todo a una tabla de etapas temporal e inserte solo nuevos títulos en su tabla de destino.

 CREATE TEMP TABLE tmp(title text); COPY tmp FROM 'path/to/file.csv'; ANALYZE tmp; INSERT INTO tbl SELECT DISTINCT tmp.title FROM tmp LEFT JOIN tbl USING (title) WHERE tbl.title IS NULL; 

Los ID deben generarse automáticamente con una columna serial tbl_id en tbl .

La construcción LEFT JOIN / IS NULL descalifica títulos ya existentes. NOT EXISTS sería otra posibilidad.

DISTINCT evita duplicates en los datos entrantes en la tabla temporal tmp .

ANALYZE es útil para asegurarse de que el planificador de consultas elija un plan sensato, y las tablas temporales no se analizan por autovacuum.

Como tiene 3 millones de elementos, puede ser temp_buffer boost la configuration de temp_buffer (solo para esta session ):

 SET temp_buffers = 1000MB; 

O todo lo que pueda pagar y es suficiente para mantener la tabla temporal en la memory RAM, que es mucho más rápido. Nota: debe hacerse primero en la session, antes de crear cualquier object temporal.

Recuperar ID

Para ver todos los ID de los datos importados:

 SELECT tbl.tbl_id, tbl.title FROM tbl JOIN tmp USING (title) 

En la misma session! Una tabla temporal se descarta automáticamente al final de la session.