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

¿Cómo funciona COPY y por qué es mucho más rápido que INSERT?

Aquí intervienen varios factores:

  • Latencia de red y retrasos de ida y vuelta
  • Gastos generales por declaración en PostgreSQL
  • Cambios de contexto y retrasos en el programador
  • COMMIT costos, si para las personas que hacen una confirmación por inserción (usted no lo está)
  • COPY -optimizaciones específicas para carga masiva

Latencia de red

Si el servidor es remoto, es posible que esté "pagando" un "precio" de tiempo fijo por declaración de, por ejemplo, 50 ms (1/20 de segundo). O mucho más para algunas bases de datos alojadas en la nube. Dado que la próxima inserción no puede comenzar hasta que la última se complete con éxito, esto significa que su máximo la tasa de inserciones es 1000/ida y vuelta-latencia-en-ms filas por segundo. Con una latencia de 50 ms ("tiempo de ping"), son 20 filas por segundo. Incluso en un servidor local, este retraso es distinto de cero. Mientras que COPY simplemente llena las ventanas de envío y recepción de TCP, y transmite filas tan rápido como la base de datos puede escribirlas y la red puede transferirlas. No se ve muy afectado por la latencia y podría estar insertando miles de filas por segundo en el mismo enlace de red.

Costos por estado de cuenta en PostgreSQL

También hay costos para analizar, planificar y ejecutar una declaración en PostgreSQL. Debe tomar bloqueos, abrir archivos de relaciones, consultar índices, etc. COPY intenta hacer todo esto una vez, al principio, luego concéntrese en cargar las filas lo más rápido posible.

Costos de cambio de tarea/contexto

Hay más costos de tiempo pagados debido a que el sistema operativo tiene que cambiar entre postgres esperando una fila mientras su aplicación la prepara y la envía, y luego su aplicación esperando la respuesta de postgres mientras postgres procesa la fila. Cada vez que cambias de uno a otro, pierdes un poco de tiempo. Se pierde potencialmente más tiempo suspendiendo y reanudando varios estados de kernel de bajo nivel cuando los procesos entran y salen de los estados de espera.

Perdiendo las optimizaciones COPY

Además de todo eso, COPY tiene algunas optimizaciones que puede usar para algunos tipos de cargas. Si no hay una clave generada y los valores predeterminados son constantes, por ejemplo, puede precalcularlos y omitir el ejecutor por completo, cargando rápidamente los datos en la tabla en un nivel inferior que omite por completo parte del trabajo normal de PostgreSQL. Si CREATE TABLE o TRUNCATE en la misma transacción COPY , puede hacer aún más trucos para hacer que la carga sea más rápida al pasar por alto la contabilidad de transacciones normal necesaria en una base de datos multicliente.

A pesar de esto, COPY de PostgreSQL todavía podría hacer mucho más para acelerar las cosas, cosas que aún no sabe cómo hacer. Podría omitir automáticamente las actualizaciones del índice y luego reconstruir los índices si está cambiando más de una cierta proporción de la tabla. Podría hacer actualizaciones de índice en lotes. Mucho más.

Costos de compromiso

Una última cosa a considerar son los costos de compromiso. Probablemente no sea un problema para ti porque psycopg2 el valor predeterminado es abrir una transacción y no comprometerse hasta que usted se lo indique. A menos que le haya dicho que use la confirmación automática. Pero para muchos controladores de bases de datos, la confirmación automática es la opción predeterminada. En tales casos, estaría haciendo una confirmación para cada INSERT . Eso significa un vaciado de disco, donde el servidor se asegura de escribir todos los datos en la memoria en el disco y les dice a los discos que escriban sus propios cachés en el almacenamiento persistente. Esto puede tardar mucho tiempo, y varía mucho según el hardware. Mi computadora portátil NVMe BTRFS basada en SSD solo puede hacer 200 fsyncs/segundo, frente a 300 000 escrituras no sincronizadas/segundo. ¡Entonces solo cargará 200 filas por segundo! Algunos servidores solo pueden hacer 50 fsyncs/segundo. Algunos pueden hacer 20.000. Entonces, si tiene que confirmar regularmente, intente cargar y confirmar en lotes, haga inserciones de varias filas, etc. Porque COPY solo se compromete uno al final, los costos de compromiso son insignificantes. Pero esto también significa COPY no puede recuperarse de los errores en la mitad de los datos; deshace toda la carga masiva.