sql >> データベース >  >> RDS >> PostgreSQL

JDBCを使用したPostgreSQLへの低速挿入

    これは、Springの「バグ」とドライバの「バグ」の組み合わせのようです。

    Springは、setValue()のたびに列のデータ型を判別しようとします。 と呼ばれます。これは、PreparedStatementMetaData.getParameterMetaData()を呼び出すことによって行われます。

    これにより、「prepare」ステートメントがデータベースに送信されるようになります。データベース自体は非常に高速ですが(私のラップトップでは、1ミリ秒を超えることはありません)、各に対して呼び出されます。 各行について、これは多くの時間を合計します(null以外の値ごとに呼び出され、約23.000回の呼び出しになります)

    パラメータメタデータをキャッシュしないことは実際には意味がないため、ある程度、これはドライバーのバグよりもSpringのバグです(少なくとも私の意見では)。 MySQL JDBCドライバーは、getParameterMetaData()をサポートしていません Springはこれを知っているので、Springがそのメソッドを呼び出すことはないため、この「バグ」はMySQLには表示されません。

    PostgresのJDBCドライバーの動作をバグとして分類できるかどうかはわかりませんが、ドライバーが最初の呼び出しの後にそのメタデータをキャッシュしていたとしたら、それは確かに素晴らしいことです。

    Springは、プロパティspring.jdbc.getParameterType.ignoreを介してステートメントメタデータを取得しないように確信できます。

    だから置くことによって:

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

    行:

    LetsGo letsGo = new LetsGo();
    

    この動作は無効になっています。

    プロパティは前に設定する必要があります Springが初期化されます。

    サンプルプロジェクトでこれを行うと、ラップトップでインサートが500ミリ秒で実行されます。

    編集

    Postgres-NGドライバーの使用に関するコメントを見た後、「公式」ドライバーとNGドライバーのソースを掘り下げました。NGドライバーは最初の呼び出し後にパラメーターメタデータをキャッシュしますが、公式ドライバーはキャッシュしません。 NGドライバーの使用が非常に高速である理由を説明します(Springで呼び出しを無効にすることなく)



    1. ora-30926エラー

    2. 数えない複数のテーブルからのレコードの; Oracle DB

    3. phpmysqlではajaxデータ応答は常に0です

    4. PHPを介したmysqlによる再帰的なツリートラバーサル