Изглежда, че това е комбинация от "бъг" на Spring и "бъг" на драйвер.
Spring се опитва да определи типа данни на колона всеки път, когато setValue()
е наречен. Той прави това чрез извикване на PreparedStatementMetaData.getParameterMetaData()
Това очевидно води до изпращане на оператор "prepare" до базата данни, което само по себе си е доста бързо (никога не повече от 1ms на моя лаптоп), но тъй като се извиква за всяка колона за всеки ред това сумира до много време (извиква се за всяка ненулева стойност, което води до приблизително 23 000 извиквания)
До известна степен това е по-скоро грешка на Spring, отколкото грешка на драйвер, защото липсата на кеширане на метаданните на параметъра всъщност няма смисъл (поне според мен). Драйверът MySQL JDBC не поддържа getParameterMetaData()
и Spring знае това и затова този "бъг" не се показва с MySQL, защото spring никога не извиква този метод.
Не съм сигурен дали поведението на JDBC драйвера на Postgres може да се класифицира като грешка, но със сигурност би било хубаво, ако драйверът кешира тези мета данни след първото извикване.
Spring може да бъде убеден да не получава метаданните на израза чрез свойството spring.jdbc.getParameterType.ignore
И така, като поставите:
System.setProperty("spring.jdbc.getParameterType.ignore", "true");
преди редът:
LetsGo letsGo = new LetsGo();
това поведение е деактивирано.
Свойството трябва да бъде зададенопреди Пролетта е инициализирана.
Когато направя това с вашия примерен проект, вмъкването се изпълнява за 500 ms на моя лаптоп.
Редактиране
След като видях коментара относно използването на драйвера Postgres-NG, се зарових в източниците на "официалния" драйвер и драйвера NG, а драйверът NG кешира метаданните на параметъра след първото извикване, докато официалният драйвер не го прави обяснява защо използването на NG драйвера е много по-бързо (без деактивиране на повикването през пролетта)