sql >> Databáze >  >> RDS >> PostgreSQL

Pomalé vkládání na PostgreSQL pomocí JDBC

Zdá se, že se jedná o kombinaci Spring „bug“ a driver „bug“.

Spring se pokusí určit datový typ sloupce pokaždé, když setValue() je nazýván. Dělá to voláním PreparedStatementMetaData.getParameterMetaData()

To zřejmě způsobí odeslání příkazu "připravte" do databáze, což je samo o sobě poměrně rychlé (na mém notebooku nikdy déle než 1 ms), ale jak se říká pro každý sloupec pro každý řádek to sčítá spoustu času (volá se pro každou hodnotu, která není nulová, což má za následek přibližně 23 000 volání)

Do jisté míry je to spíše chyba Spring než chyba ovladače, protože neukládání metadat parametrů do mezipaměti opravdu nedává smysl (alespoň podle mého názoru). Ovladač MySQL JDBC nepodporuje getParameterMetaData() a Spring to ví, a tak se tato "chyba" v MySQL nezobrazí, protože jaro tuto metodu nikdy nevolá.

Nejsem si jistý, jestli chování ovladače Postgres JDBC lze klasifikovat jako chybu, ale určitě by bylo hezké, kdyby ovladač ukládal tato meta data po prvním volání do mezipaměti.

Spring může být přesvědčen, že metadata příkazu nezíská prostřednictvím vlastnosti spring.jdbc.getParameterType.ignore

Takže zadáním:

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

před řádek:

LetsGo letsGo = new LetsGo();

toto chování je zakázáno.

Vlastnost musí být nastavena před Jaro je inicializováno.

Když to udělám s vaším ukázkovým projektem, vložka běží na mém notebooku za 500 ms.

Upravit

Poté, co jsem viděl komentář týkající se použití ovladače Postgres-NG, zapátral jsem ve zdrojích „oficiálního“ ovladače a ovladače NG a ovladač NG po prvním volání ukládá metadata parametru do mezipaměti, zatímco oficiální ovladač ne, který vysvětluje, proč je použití ovladače NG mnohem rychlejší (bez deaktivace volání na jaře)



  1. Spouštěč MySQL nemůže aktualizovat tabulku – získává ERROR 1442

  2. Nejrychlejší postgreSQL ekvivalentní k MySQL UTC_DATE() (získání data UTC)?

  3. Jaký je rozdíl mezi „není v“ a „neexistuje“?

  4. Rozdělit řetězec podle pozice oddělovače pomocí oracle