with postgres java performance postgresql jdbc

java - with - jpa hibernate postgresql sequence



Consejos para acelerar JDBC escribe? (4)

Estoy escribiendo un programa que escribe muchas veces en una base de datos de Postgres. En un escenario típico estaría escribiendo, digamos, 100.000 filas en una tabla que está bien normalizada (tres claves enteras extranjeras, cuya combinación es la clave principal y el índice de la tabla). Estoy usando PreparedStatements y executeBatch (), pero solo puedo presionar digamos 100k filas en unos 70 segundos en mi computadora portátil, cuando la base de datos integrada que estamos reemplazando (que tiene las mismas restricciones e índices de clave externa) lo hace en 10.

Soy nuevo en JDBC y no espero que venza una base de datos integrada personalizada, pero esperaba que fuera solo 2-3 veces más lenta, no 7x. ¿Algo obvio que me pueda estar perdiendo? ¿Importa el orden de las escrituras? (es decir, decir si no es el orden del índice?). Cosas a las que mirar para exprimir un poco más de velocidad?


Obviamente, puede intentar cambiar el tamaño de su lote para encontrar el mejor tamaño para su configuración, pero dudo que gane un factor 3.

También podría tratar de ajustar la estructura de su base de datos. Es posible que tenga mejores actuaciones cuando use un solo campo como clave principal que utilizando un PK compuesto. Dependiendo del nivel de integridad que necesita, puede ahorrar bastante tiempo al desactivar las comprobaciones de integridad en su base de datos.

También puede cambiar la base de datos que está utilizando. Se supone que MySQL es bastante bueno para las inserciones simples de alta velocidad ... y sé que hay una bifurcación de MySQL que intenta cortar las funcionalidades para obtener rendimientos muy altos en un acceso altamente concurrente.

Buena suerte !


intente deshabilitar los índices y volver a habilitarlos después del inserto. también, envuelva todo el proceso en una transacción


Este es un problema con el que he tenido que lidiar a menudo en mi proyecto actual. Para nuestra aplicación, la velocidad de inserción es un cuello de botella crítico. Sin embargo, hemos descubierto que para la gran mayoría de los usuarios de bases de datos, la velocidad de selección es su cuello de botella principal, por lo que descubrirá que hay más recursos relacionados con ese problema.

Así que aquí hay algunas soluciones que hemos creado:

En primer lugar, todas las soluciones implican el uso del comando COPY postgres. El uso de COPY para importar datos en postgres es, de lejos, el método más rápido disponible. Sin embargo, el controlador JDBC de forma predeterminada actualmente no es compatible con COPY en el socket de red. Entonces, si desea usarlo, deberá hacer una de estas dos soluciones:

  1. Un controlador JDBC parcheado para admitir COPY, como este.
  2. Si los datos que está insertando y la base de datos están en la misma máquina física, puede escribir los datos en un archivo en el sistema de archivos y luego usar el comando COPIA para importar los datos en forma masiva.

Otras opciones para aumentar la velocidad son el uso de JNI para acceder a la API postgres para que pueda hablar sobre el socket de Unix, eliminar índices y el proyecto pg_bulkload . Sin embargo, al final, si no implementa COPY siempre encontrará un rendimiento decepcionante.


Verifica si tu conexión está configurada en autoCommit. Si autoCommit es verdadero, entonces si tiene 100 elementos en el lote cuando llama a executeBatch, emitirá 100 commits individuales. Eso puede ser mucho más lento que invocar executingBatch () seguido de una única confirmación explícita ().

Evitaría la tentación de soltar índices o claves externas durante la inserción. Pone la tabla en un estado inutilizable mientras se está ejecutando su carga, ya que nadie puede consultar la tabla mientras los índices se han ido. Además, parece bastante inofensivo, pero ¿qué haces cuando intentas reactivar la restricción y falla porque ha ocurrido algo que no esperabas que sucediera? Un RDBMS tiene restricciones de integridad por una razón, y desactivarlas incluso "por un tiempo" es peligroso.