3

私の問題はこれです:MySQLからのJDBCTemplateを介してSpringで約150万行のデータを処理しようとしています。このように多数の行があるため、ここで提案されているようにRowCallbackHandlerクラスを使用しています。

コードは実際には機能していますが、遅いです...フェッチサイズを何に設定しても、フェッチごとに約350レコードを取得しているように見えますが、フェッチ間に2〜3秒の遅延があります(ログの監視から) 。storeコマンドをコメントアウトしてみたところ、動作が変わらないことを確認したので、書き込みに問題はありません。

6つの列があり、1つだけがvarcharであり、その1つは25文字しかないため、スループットが問題になることはわかりません。

理想的には、一度に30000〜50000行のようにしたいと思います。それを行う方法はありますか?

これが私のコードです:


    protected void runCallback(String query, Map params, int fetchSize, RowCallbackHandler rch) 
            throws DatabaseException {
        int oldFetchSize = getJdbcTemplate().getFetchSize();
        if (fetchSize > 0) {
            getJdbcTemplate().setFetchSize(fetchSize);
        }
        try {
            getJdbcTemplate().query(getSql(query), rch);
        }
        catch (DataAccessException ex) {
            logger.error(ExceptionUtils.getStackTrace(ex));
            throw new DatabaseException( ex.getMessage() );         
        }
        getJdbcTemplate().setFetchSize(oldFetchSize);
    }

and the handler:

public class SaveUserFolderStatesCallback implements RowCallbackHandler {
        @Override
        public void processRow(ResultSet rs) throws SQLException {
            //Save each row sequentially.
            //Do NOT call ResultSet.next() !!!!

            Calendar asOf = Calendar.getInstance();
            log.info("AS OF DATE: " + asOf.getTime());
            Long x = (Long) rs.getLong("x");
            Long xx = (Long) rs.getLong("xx");
            String xxx = (String) rs.getString("xxx");
            BigDecimal xxxx = (BigDecimal)rs.getBigDecimal("xxxx");
            Double xxxx = (budgetAmountBD == null) ? 0.0 : budgetAmountBD.doubleValue();
            BigDecimal xxxxx = (BigDecimal)rs.getBigDecimal("xxxxx");
            Double xxxxx = (actualAmountBD == null) ? 0.0 : actualAmountBD.doubleValue();           

            dbstore(x, xx, xxx, xxxx, xxxxx, asOf);
        }       

    }
4

3 に答える 3

0

答えは実際にはsetFetchSize(Integer.MIN_VALUE)を実行することですが、これはStatement.setFetchSizeの規定されたコントラクトに完全に違反し、mysqljavaコネクタはこの値を使用して結果セットをストリーミングします。これにより、パフォーマンスが大幅に向上します。

修正のもう1つの部分は、負のフェッチサイズに対応する(Spring)JdbcTemplateの独自のサブクラスを作成する必要があることです...実際、ここでコード例を取り上げました。ここで、fetchSize(Integer .MIN_VALUE)

http://javasplitter.blogspot.com/2009/10/pimp-ma-jdbc-resultset.html

助けてくれてありがとう!

于 2012-05-09T13:43:02.877 に答える
0

そして、あなたの質問は何ですか?検索/並べ替えるフィールドのindexexを作成してみてください。それは役に立ちます。

2番目の戦略:メモリキャッシュの実装。または、Hibernateと第2レベルのキャッシュを使用します。

この両方の技術により、クエリの実行を大幅に高速化できます。

于 2012-05-08T17:49:11.743 に答える
0

いくつかの質問

  1. DBに直接クエリを実行する場合、どのくらい時間がかかりますか。もう1つの問題は、アプリケーションとDBホスト間のASYNC_NETWORK_IOの遅延である可能性があります。

  2. Springを使わずにチェックしましたか

于 2012-05-08T17:49:40.870 に答える