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

Inserción lenta en PostgreSQL usando JDBC

Parece que esta es una combinación de un "error" de Spring y un "error" del controlador.

Spring intenta determinar el tipo de datos de una columna cada vez que setValue() se llama. Lo hace llamando a PreparedStatementMetaData.getParameterMetaData()

Aparentemente, esto hace que se envíe una declaración de "preparación" a la base de datos, que en sí misma es bastante rápida (nunca más de 1 ms en mi computadora portátil), pero como se llama para cada columna para cada fila, esto suma mucho tiempo (se llama para cada valor no nulo que da como resultado aproximadamente 23,000 llamadas)

Hasta cierto punto, esto es más un error de Spring que un error del controlador porque no almacenar en caché los metadatos de los parámetros realmente no tiene sentido (al menos en mi opinión). El controlador MySQL JDBC no es compatible con getParameterMetaData() y Spring lo sabe, por lo que este "error" no aparece con MySQL porque Spring nunca llama a ese método.

No estoy seguro de si el comportamiento del controlador JDBC de Postgres se puede clasificar como un error, pero sería bueno si el controlador almacenara en caché esos metadatos después de la primera llamada.

Se puede convencer a Spring de que no obtenga los metadatos de la declaración a través de la propiedad spring.jdbc.getParameterType.ignore

Entonces, al poner:

System.setProperty("spring.jdbc.getParameterType.ignore", "true");

antes la línea:

LetsGo letsGo = new LetsGo();

este comportamiento está deshabilitado.

La propiedad debe establecerse antes Spring se inicializa.

Cuando hago eso con su proyecto de muestra, la inserción se ejecuta en 500 ms en mi computadora portátil.

Editar

Después de ver el comentario sobre el uso del controlador Postgres-NG, busqué en las fuentes del controlador "oficial" y el controlador NG, y el controlador NG almacena en caché los metadatos del parámetro después de la primera llamada, mientras que el controlador oficial no lo hace. explica por qué usar el controlador NG es mucho más rápido (sin deshabilitar la llamada en Spring)