2016-10-23 14 views
1

私は、結果セットで返された何百万ものレコードを繰り返し処理し、それらをいくつかのデータ構造体に格納するというこの要件を持っています。私は、関連する例や参照を見つけることができませんでした。 JOOQは私が望むかもしれない何かをしているようだが、それは無料ではないようだ。私はそれを達成することができる可能性がありますが、Javaの8ストリームを使用して期待していたが、例や書き込みが私に向かう任意の方向を与えるようだ。私は他の選択肢にもオープンしています。
このSOリファレンスに基づいて:resultset parallel私は以下のように試みましたが、パフォーマンスメトリックでは以下のようにパフォーマンスの改善は見られませんでした。
CODE: シーケンシャルイテレーション:Javaで結果セットを並行して読み込み/処理する

while(rs.next()) { 
    System.out.println(rs.getString(1)); 
    } 

ストリームとspliterator使用:

Stream<String> s = StreamSupport.stream(new Spliterators.AbstractSpliterator<String>(Long.MAX_VALUE, 
       Spliterator.ORDERED) { 

      @Override 
      public boolean tryAdvance(Consumer<? super String> action) { 
       try { 
        if (!rs.next()) 
         return false; 
        action.accept(rs.getString(1)); 
       } catch (SQLException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
       return true; 
      } 
     }, true); 
     s.forEach(System.out::println); 

レコードの総数:シーケンシャルで撮影した3759
時間:Streamsで撮影した〜83.8秒
時間: 〜83.5秒

誰でもこれを確認し、私が実装されたストリームは正しくありません。

+5

多分この質問と回答は役に立ちます:http://stackoverflow.com/a/32232173/4105457 – Flown

+1

タイトルと質問の関連付けに問題があります。 – EJP

+0

そこには多くの結果セット処理の例があるので、あなたの問題は別の場所にあると思いますか?私はあなたの質問をはるかに具体化できるはずだと思います。今のところ、私は答えがあまりにも不明だと思う。 –

答えて

4

ResultSetは並列処理できません。クエリーのために変更する必要のある変更可能な状態を組み込んだイテレータの一種です。特に、ResultSetには、移動する必要のある現在の行があり、読み取ることができます。索引によってアクセスされる行内の値であっても、この仕様ではスレッドの安全性の保証はなく、順序がずれていることを読み取ることが基礎となるデータベースでサポートされていない可能性があることに言及しています。

したがって、並列処理の恩恵を受ける唯一の操作は、後続の操作の連鎖ですが、連鎖操作がSystem.out::printlnの場合は悪化します。印刷処理は並列処理の恩恵を受けるだけでなく、すべての標準実装でPrintStreamSystem.outにあり、すべての書き込み操作をターゲット出力に同期させます。

並列処理の恩恵を受ける計算力の強い操作を連鎖しても、高価なデータベース操作が全体の実行時間を支配する可能性があります。だから、データベースをフィルタリングして、データをできるだけ集約してから、Java側に転送することが重要です。

+0

:(今でも私が今解決しているすべての解決策で苦しんでいます。私はまだこの質問を開いて、誰かがハック/回避策を提案できるかどうか確認します。 –

関連する問題