2

DBパッケージの一部である関数の呼び出しを実行しています。このパッケージは2つの場所に展開されます。1つのローカルと別のリモート(大西洋を渡って)。

SpringJDBCテンプレートを介してデータを取得しています。

約1000行(それほど多くはない)を返す関数が1つあり、これはローカルでデータを取得する場合は約1.5秒かかりますが、リモートでデータを取得する場合は約12秒かかります。

すべてのサンプルコードで、名前が変更され、コードが少し簡略化されています。

現在のJavaコードの例を参照してください。

SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(getDataSource())
                                            .withSchemaName(MY_SCHEMA_NAME)
                                            .withCatalogName("REFCURSOR_PKG")
                                            .withFunctionName("GET_DATA")
                                            .returningResultSet("RESULT_SET", new DataEntryMapper());

        SqlParameterSource params = new MapSqlParameterSource()
                                    .addValue("the_name", name)
                                    .addValue("the_rev", rev);

        Map resultSet = simpleJdbcCall.execute(params);
        ArrayList list = (ArrayList) resultSet.get("RESULT_SET");

RowMapperクラスは次のようになります。

class RouteDataEntryMapper implements RowMapper {
        public RouteDataEntry mapRow(ResultSet resultSet, int rowNum) throws SQLException {
            return new DataEntry(resultSet.getString("name"), 
                                    Integer.parseInt(resultSet.getString("rev"));
        }
    }

SQLパッケージ仕様スニペット:

TYPE REF_CURSOR IS REF CURSOR;  

SQL関数:

 FUNCTION GET_ROUTE_DATA(the_name VARCHAR2, the_rev VARCHAR2) RETURN REF_CURSOR AS

  RESULT_SET REF_CURSOR;

  BEGIN
    OPEN RESULT_SET FOR
    select *
    from table_name tn
    where tn.name = the_name
    and tn.rev = the_rev;

    RETURN RESULT_SET;

    CLOSE RESULT_SET;

    EXCEPTION WHEN OTHERS THEN
      RAISE;

  END GET_ROUTE_DATA;

通常のボイラープレートJDBCも使用してみました(接続の作成、ステートメントの準備、ステートメントの実行、RESULT_SETからのデータの取得など)。RESULT_SETをループしてデータを抽出し、そこにデータを抽出するのに大部分の時間が費やされていることがわかりました。いくつかのポジョ。上記のSpringコードの場合、ほとんどの時間はexecute()メソッドに費やされましたが、これはおそらく、その時点でRowMapperを使用してオブジェクトを作成したためです。

したがって、それらの間の共通領域は、次のようなアクションの実行です。

rs.getString("name")

ここに問題があると思いますが、間違っている可能性があります。

私が言ったように、ローカルでは遅延は問題ありませんが、リモートでは時間がかかりすぎます。これは、すべてのrs.getのDBに送信されるためです...?これを行うためのより良い方法はありますか?

前もって感謝します。

4

2 に答える 2

2

rs.getString("名前")

ResultSet.get*(String columnName)ResultSet.get*(int columnNaumber)少し速いほうに置き換えることができますが、ここでの主な問題は疑わしいです。

これは、すべての rs.get... で DB にアクセスするためですか?

それは本当にドライバーに依存しますが、そうではないと思います。キャッシュされた結果セットの場合、カーソルをスクロールするとサーバーに移動する可能性がありますが、ラウンドトリップごとに大量の行がフェッチされます。

私が持っているさらに2つの提案は次のとおりです。

  • ネットワーク スニッフィング ユーティリティを使用して、転送中のデータを確認します
  • プリフェッチなどのオプションについては、ドライバーを確認してください。
于 2012-09-20T17:47:34.190 に答える