12

INSERTバッチ( defaultBatchValue) とマスSELECT( )を高速化するために、いくつかの特定の Oracle JDBC 接続プロパティを設定する必要がありますdefaultRowPrefetchDBCP でこれを達成する方法について提案を受けました (M. Deinum に感謝します)。

  • デフォルトの Tomcat jdbc 接続プールを維持する
  • 構成のために application.yml を保持します

将来的にサポートまたは同様の機能要求について考えていたspring.datasource.custom_connection_propertiesので、これがすでに可能であるふりをしようとしました。DataSource の作成中に関連情報を渡すことでこれを行い、次のように DataSource の作成を操作しました。

@Bean
public DataSource dataSource() {
    DataSource ds = null;

    try {
        Field props = DataSourceBuilder.class.getDeclaredField("properties");
        props.setAccessible(true);
        DataSourceBuilder builder = DataSourceBuilder.create();
        Map<String, String> properties = (Map<String, String>) props.get(builder);

        properties.put("defaultRowPrefetch", "1000");
        properties.put("defaultBatchValue", "1000");

        ds = builder.url( "jdbc:oracle:thin:@xyz:1521:abc" ).username( "ihave" ).password( "wonttell" ).build();

        properties = (Map<String, String>) props.get(builder);

        log.debug("properties after: {}", properties);
    } ... leaving out the catches ...
    }
    log.debug("We are using this datasource: {}", ds);
    return ds;
}

ログで、正しい DataSource を作成していることがわかります。

2016-01-18 14:40:32.924 DEBUG 31204 --- [           main] d.a.e.a.c.config.DatabaseConfiguration   : We are using this datasource: org.apache.tomcat.jdbc.pool.DataSource@19f040ba{ConnectionPool[defaultAutoCommit=null; ...

2016-01-18 14:40:32.919 DEBUG 31204 --- [           main] d.a.e.a.c.config.DatabaseConfiguration   : properties after: {password=wonttell, driverClassName=oracle.jdbc.OracleDriver, defaultRowPrefetch=1000, defaultBatchValue=1000, url=jdbc:oracle:thin:@xyz:1521:abc, username=ihave}

アクチュエーターは、コードがデータソースを置き換えたことを示しています。

ここに画像の説明を入力

しかし、アプリケーションのプロファイリング中に確認できるように、設定はアクティブ化されていません。defaultRowPrefetchがアクティブ化された10場合よりSELECTもはるかに遅くなります。1000

4

4 に答える 4

3

@Cyrilによる回答を補完する追加情報。賛成票を投じたい場合は、私のものではなく、彼の答えを使用してください。

データベース接続の作成中に最終的に使用される追加の接続プロパティを簡単に設定できることに少し戸惑いました。そこで、ちょっと調べてみました。

spring.datasource.connectionPropertiesリファレンスには記載されていませんこのため、問題を作成しました。Spring Boot YML エディターを使用していれば、どのプロパティがサポートされているかがわかります。and hitを作成するときにSTSが提案する内容は次のとおりです。application.ymlCtrl+Space

spring.datasource のオートコンプリート

バインディングが緩和されているため、ダッシュは重要ではありませんが、文字どおりに解釈すると、プロパティ名はspring.datasource.connection-properties.

application.yml の正しいセットアップは次のようになります。

spring:
    datasource:
        connection-properties: defaultBatchValue=1000;defaultRowPrefetch=1000
        ...

SELECTこれは、質量s のperf4j 測定によって証明されているように、尊重されます。

前:

2016-01-19 08:58:32.604 INFO 15108 --- [メイン] org.perf4j.TimingLogger: 開始 [1453190311227] 時間 [1377] タグ [要素を取得]

後:

2016-01-19 08:09:18.214 INFO 9152 --- [メイン] org.perf4j.TimingLogger: 開始 [1453187358066] 時間 [147] タグ [要素を取得]

SQL ステートメントの完了にかかる時間は 1377 ミリ秒から 147 ミリ秒に短縮され、パフォーマンスが大幅に向上しています。

于 2016-01-19T08:13:44.837 に答える
1

Tomcat コードを少し調べてみたところ、が実際にプールの接続を生成するために使用されるオブジェクトであることdataSource.getPoolProperties().getDbProperties()がわかりました。Properties

@m-deinum で言及されているアプローチを使用するBeanPostProcessorが、代わりにそれを使用してdbProperties同様のデータを入力する場合は、プロパティを固定して Oracle ドライバーに渡す方法でプロパティを追加できるはずです。

import java.util.Properties;
import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.pool.PoolConfiguration;

@Component
public class OracleConfigurer implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
        if (bean instanceof DataSource) {
            DataSource dataSource = (DataSource)bean;
            PoolConfiguration configuration = dataSource.getPoolProperties();
            Properties properties = configuration.getDbProperties();
            if (null == properties) properties = new Properties();
            properties.put("defaultRowPrefetch", 1000);
            properties.put("defaultBatchValue", 1000);
            configuration.setDbProperties(properties);
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
        return bean;
    }
}
于 2016-09-13T23:29:54.793 に答える