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

MySQLを使用した大規模な結果セットのストリーミング

    フェッチサイズを設定するだけでは、正しい方法ではありません。 <コードの javadoc> Statement#setFetchSize() すでに次のように述べています:

    JDBCドライバーにヒントを提供します データベースからフェッチする必要のある行数について

    ドライバーは実際にはヒントを自由に適用または無視できます。一部のドライバーはそれを無視し、一部のドライバーはそれを直接適用し、一部のドライバーはより多くのパラメーターを必要とします。 MySQL JDBCドライバーは、最後のカテゴリーに分類されます。 MySQLJDBCドライバーを確認した場合ドキュメント 、次の情報が表示されます(ヘッダー ResultSetまで約2/3下にスクロールします ):

    この機能を有効にするには、次の方法でステートメントインスタンスを作成する必要があります。

    stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY);
    stmt.setFetchSize(Integer.MIN_VALUE);
    

    全体をお読みください ドキュメントのセクションでは、このアプローチの警告についても説明しています。関連する引用は次のとおりです:

    このアプローチにはいくつかの注意点があります。接続で他のクエリを発行する前に、結果セットのすべての行を読み取る(または閉じる)必要があります。そうしないと、例外がスローされます。

    (...)

    ステートメントがトランザクションのスコープ内にある場合、トランザクションが完了するとロックが解放されます(これは、ステートメントが最初に完了する必要があることを意味します)。他のほとんどのデータベースと同様に、ステートメントで保留中のすべての結果が読み取られるか、ステートメントのアクティブな結果セットが閉じられるまで、ステートメントは完了しません。

    それでも解決しない場合は、 OutOfMemoryError 例外ではありません )、問題は、すべてのデータをすぐに処理するのではなく、Javaのメモリに保存している可能性があります。 データが到着するとすぐに。これには、コードをさらに変更する必要があり、完全に書き直す必要があります。 こちら> 。



    1. 新しいAzureSQLデータベースの標準階層サイズ

    2. 良いインデックスが何であるかをどうやって知るのですか?

    3. Common Table Expression(CTE)を使用する場合

    4. OracleSQLのCaseステートメントの一部でエイリアスを使用する