0

この SQL クエリのパフォーマンスを最適化したいと考えています。このハッシュテーブルに 100 万個のキーを入力すると、クエリに約 1 分かかります。このJavaメソッドを最適化して実行を高速化するにはどうすればよいですか?

private HashMap<String, Boolean> selectedIds = new HashMap<>();

public void deleteSelectedIDs() throws SQLException {

        if (ds == null) {
            throw new SQLException();
        }

        Connection conn = ds.getConnection();
        if (conn == null) {
            throw new SQLException();
        }

        PreparedStatement ps = null;
        ResultSet resultSet = null;

        try {
            conn.setAutoCommit(false);
            boolean committed = false;
            try {
                String sqlDeleteQuery = "DELETE FROM ACTIVESESSIONSLOG WHERE ASESSIONID = ?";

                Set<String> keySet = selectedIds.keySet();
                String[] keys = new String[]{};
                keys = selectedIds.keySet().toArray(keys);
                ps = conn.prepareStatement(sqlDeleteQuery);

                for (int i = 0; i < keys.length; i++) {
                    if (selectedIds.get(keys[i]).booleanValue()) {
                        ps.setString(1, keys[i]);
                        ps.executeUpdate();
                        ps.clearParameters();
                        selectedIds.put(keys[i], false); //get(keys[i]) = false;
                    }
                }

                conn.commit();
                committed = true;

                //selectedIds.clear();
            } finally {
                if (!committed) {
                    conn.rollback();
                }
            }
        } finally {
            ps.close();
            conn.close();
        }
    }
4

4 に答える 4

5

JDBC ドライバーがサポートしている場合は、バッチ処理を使用してください。使い方は簡単で、このタイプのシナリオでは非常にうまく機能する傾向があります。

于 2012-05-24T16:28:49.703 に答える
3

誰かがより良いアイデアを持っているかもしれませんが、キーのリストを一時テーブルを介して Oracle に渡し、PL/SQL 関数内でループを実行することを検討したことがありますか。トラフィックが低下し、DB が処理を行います。

于 2012-05-24T16:30:03.340 に答える
2

一時テーブルを作成し、そこにすべてのIDを挿入します。次に、一時テーブルで見つかったものに対して1回の削除を実行します。

于 2012-05-24T16:32:16.843 に答える
2

CallableStatementと oracle procedureを使用する方がよいと思います。

スニペット

SQL> create type temp_tbl
  2  is
  3  table of number;
  4  /

...


SQL> create or replace procedure stored_p
  2  (
  3    list in temp_tbl,
  4    p_rc  out sys_refcursor )
  5  as
  6  begin
  7    open
  8   p_rc for delete from ACTIVESESSIONSLOG  where ASESSIONID
      in (select * from table(list));
  9  end;
 10  /
于 2012-05-24T16:35:32.220 に答える