Il semble que ce soit une combinaison d'un "bug" de Spring et d'un "bug" de pilote.
Spring essaie de déterminer le type de données d'une colonne à chaque fois setValue()
est appelé. Il le fait en appelant PreparedStatementMetaData.getParameterMetaData()
Cela provoque apparemment l'envoi d'une instruction "préparer" à la base de données, ce qui en soi est assez rapide (jamais plus de 1 ms sur mon ordinateur portable) mais comme il est appelé pour chaque colonne pour chaque ligne, cela représente beaucoup de temps (il est appelé pour chaque valeur non nulle, ce qui entraîne environ 23 000 appels)
Dans une certaine mesure, il s'agit plus d'un bogue de Spring que d'un bogue de pilote, car ne pas mettre en cache les métadonnées des paramètres n'a pas vraiment de sens (du moins à mon avis). Le pilote MySQL JDBC ne prend pas en charge getParameterMetaData()
et Spring le sait et donc ce "bogue" n'apparaît pas avec MySQL car Spring n'appelle jamais cette méthode.
Je ne sais pas si le comportement du pilote JDBC de Postgres peut être classé comme un bogue, mais ce serait certainement bien si le pilote mettait en cache ces métadonnées après le premier appel.
Spring peut être convaincu de ne pas obtenir les métadonnées de l'instruction via la propriété spring.jdbc.getParameterType.ignore
Donc en mettant :
System.setProperty("spring.jdbc.getParameterType.ignore", "true");
avant la ligne :
LetsGo letsGo = new LetsGo();
ce comportement est désactivé.
La propriété doit être définie avant Le ressort est initialisé.
Lorsque je fais cela avec votre exemple de projet, l'insert s'exécute en 500 ms sur mon ordinateur portable.
Modifier
Après avoir vu le commentaire concernant l'utilisation du pilote Postgres-NG, j'ai creusé dans les sources du pilote "officiel" et du pilote NG, et le pilote NG met en cache les métadonnées des paramètres après le premier appel alors que le pilote officiel ne le fait pas. explique pourquoi l'utilisation du pilote NG est tellement plus rapide (sans désactiver l'appel au printemps)