2016-05-27 6 views
-2

私は以下のコードを持っていますが、これは非常に簡単ですが、反復処理中のマップに多くのエントリがあると、明らかに許容できないほど遅くなります。forループ内で実行されたSELECTクエリをより速く効率的に実行するにはどうすればよいですか?

public Map<String, String> getIdToEmailMapping(Connection conn, Map<String, String> map) { 

    Map<String, String> id_email_map = new HashMap<String, String>(); 

    try { 
     PreparedStatement stmt = null; 
     String sql = "SELECT EMAIL FROM DATA_VIEW WHERE URL=?"; 
     stmt = conn.prepareStatement(sql); 
     for (Map.Entry<String, String> entry : map.entrySet()) {  
      stmt.setString(1, entry.getValue()); // set URL in sql statement 
      ResultSet rs = stmt.executeQuery(); 
      while (rs.next()) { 
       String email = rs.getString("EMAIL"); 
       String id = entry.getKey(); 
       id_email_map.put(id, email); 
      } 
      rs.close();   
     } 
     stmt.close(); 
    } catch (SQLException se) { 
     se.printStackTrace(); 
    } 

    return id_email_map; 

} 

私はこの実装は単に悪いですので、マップがエントリの数千を持っていることを期待...しかし、私はそれを他の方法で行うことができるかどうかわかりません。私はこの種の問題のSQLトリックを探してみましたが、何も見つかりませんでした。誰にもアイデアはありますか?

+0

「(ID1、ID2、ID3 ....のURLのDATA_VIEW WHERE欄からEMAILを選択してください」と言って、100または1000のエントリのバッチを実行できます。また、try-with-resourceブロックを使用して文を閉じます。 – pandaadb

+0

oracle(タグのような)を使用していると仮定すると、結果全体を一時表に挿入することができます。テーブルを数えます。特定の結果を得るには、ROWNUMとLIMITを使用して結果のグループを選択します(例:ROWNUM> 500 LIMIT 500、結果501-1000)。一貫性のある順序を使用して重複を避けるようにしてください –

+0

何千ものエントリがどこにあるのかを踏ん張り、全体をもっと速く動かす方法を探してみることをお勧めします。通常、テーブルを結合するのは簡単です。 –

答えて

0

たぶん、このような何か:

static void call(final Connection con) throws SQLException { 
     Map<String, String> emailMap = new HashMap<>(); 
     emailMap.put("id1", "someVal"); 
     emailMap.put("id2", "someVal"); 
     emailMap.put("id3", "someVal"); 
     emailMap.put("id4", "someVal"); 

     String collect = emailMap.keySet().stream().collect(Collectors.joining(",")); 


     String query = " SELECT EMAIL FROM DATA_VIEW WHERE URL IN (" + collect + ")"; 


     try (Statement s = con.createStatement()) { 

      ResultSet executeQuery = s.executeQuery(query); 
      // do your result processing 
     } 

    } 

代わりに個別にすべてのあなたのURLを問い合わせるので、すべてのあなたのIDまたはURLの1つのクエリを送信することができます。クエリは次のようになります。

SELECT EMAIL FROM DATA_VIEW WHERE URL in (id2,id1,id4,id3) 

+0

私はそれがむしろStringと考えています。collect = emailMap.values()... –

+0

これは私のために働いていました。 IN句を使用して1000エントリのバッチを実行すると、その処理が高速になりました。私は私の質問をする前にIN演算子を使って作業を試みましたが、うまくいきませんでしたので、問題が解決しないと思いました。私のプログラムの特定の要件を満たすために、コードとクエリを少し修正しなければならなかったことが分かります。ありがとう! – tmcf

関連する問題