Oracle JDBC 优化:在 Spring 引导应用程序中启用 PreparedStatement 缓存

Posted

技术标签:

【中文标题】Oracle JDBC 优化:在 Spring 引导应用程序中启用 PreparedStatement 缓存【英文标题】:Oracle JDBC Optimization : Enable PreparedStatement caching in a Spring boot Application 【发布时间】:2020-03-10 07:57:45 【问题描述】:

我有一个连接到 Oracle 数据库的 Spring Boot REST 应用程序。我们使用 JdbcTemplate 使用 JDBC。 Oracle 数据库属性是通过这 3 个 application.properties 设置获得的:

spring.datasource.url
spring.datasource.username
spring.datasource.password

此应用程序正在使用 HikariCP。从 HikariCP 网站上,我了解到这个池不缓存 PreparedStatements,因为 JDBC 驱动程序是最好的设置。

现在,我将在哪里以及指定什么来确保这些:

    Oracle JDBC 驱动程序 (ojdbc7.jar) 缓存 PreparedStatements。有没有办法自定义它可以缓存的 PreparedStatements 的数量。

    来自https://howtodoinjava.com/java/jdbc/best-practices-to-improve-jdbc-performance/,我们看到了

    确保您的数据库设置为最大数据包大小,并且 驱动程序匹配该数据包大小。为了获取更大的结果集, 这减少了之间发送/接收的总数据包数量 驱动程序和服务器。

根据上述情况,需要哪些步骤

    查找 Oracle DB 服务器数据包大小 查看 Oracle DB 服务器是否设置为最大数据包大小 查找设置 Oracle JDBC 驱动程序的 (ojdbc8.jar) 数据包大小。

任何其他 (Oracle) JDBC 性能优化技巧将不胜感激。

【问题讨论】:

在dba网站问更合适吗? dba.stackexchange.com/questions/tagged/oracle @user7294900 不是真的,因为这是关于配置 JDBC 驱动程序(假设它甚至有这样的配置选项),这使得这是一个编程问题,而不是 DBA 问题。 【参考方案1】:

嗨,启用准备好的语句缓存功能与 Spring 和 REST 无关。这个函数只是你的数据源、你的 JDBC 驱动程序和你的数据库之间的协商问题。为了了解如何设置它,请阅读有关您的驱动程序、数据源和数据库的相关文档。

对于 Hikari,执行此操作的正确方法是(注意 datasource2,重命名为 datasource 以启用自动配置):

spring:
  datasource2:
      dataSourceClassName: com.zaxxer.hikari.HikariDatasource
       .....
       ......
      configuration:
            maximumPoolSize: 25  
            data-source-properties:
               ImplicitCachingEnabled: true
               MaxStatements: 100

配置中的属性将直接传递给底层驱动程序。

@Bean
@ConfigurationProperties("spring.datasource2")
public DataSourceProperties dataSourceProperties2() 
    return new DataSourceProperties();


@Bean()
@ConfigurationProperties("spring.datasource2.configuration")
public DataSource hikariDatasource() 


    return dataSourceProperties2().initializeDataSourceBuilder().build();

此示例使用底层数据源的手动初始化。

【讨论】:

这是 mysql 配置,cachePrepStmts 是 MySQL JDBC 驱动程序选项,请参阅 github.com/brettwooldridge/HikariCP/blob/… 和 dev.mysql.com/doc/connector-j/5.1/en/… @KarolDowbecki 实际上这个例子是在 DB2 上运行的 :) Point is data-source-properties 是一个代理,它将属性传递给驱动程序,因此如果驱动程序没有cachePrepStmts 属性,它将无法工作。 ojdbc8 驱动没有这个属性。 @KarolDowbecki 也许您应该将问题更改为“您需要什么属性才能在 Oracle 中启用语句缓存”,而不是涉及 Spring Boot REST 等。 docs.oracle.com/cd/B19306_01/java.102/b14355/… @AlexandarPetrov:嗨,我是这里的 OP。我删除了 REST 部分。我需要使用 ojdbc7.jar 的 Oracle 11/12 的配置属性【参考方案2】: 通过启用语句缓存

oracleDataSource.setImplicitCachingEnabled(true)

选择正确的缓存大小以充分利用内存

connection.setStatementCacheSize(10) 尽量接近最常用语句的数量 默认语句缓存大小为 10

如果您无法将应用程序更改为使用语句,则回退 缓存

session_cached_cursors = 50 Connection.setStatementCacheSize(10)

【讨论】:

我无权访问 OracleDatasource。我可以访问的只是 JdbcTemplate ,我将从中获取 Hikari 数据源。我也不去连接级别——我在 JdbcTemplate 级别工作。【参考方案3】:

首先检查文档以确保您的ojdbc8.jar 与数据库服务器版本匹配。 11g、11gR2、12c 有不同版本的ojdbc8.jar

根据this answer,您需要在JDBC 驱动程序中设置oracle.jdbc.implicitStatementCacheSize 属性。 This article 提到了更多 JDBC 驱动程序属性,例如oracle.jdbc.freeMemoryOnEnterImplicitCacheoracle.jdbc.maxCachedBufferSize。您需要查看驱动程序版本的文档以确认这些属性可用。

这可以使用 Spring Boot HikariCP spring.datasource.hikari.data-source-properties 选项传递。仔细检查您的 Spring Boot 版本的文档,此属性至少重命名过一次:

application.yaml

spring:
  datasource:
    hikari:
      data-source-properties:
        oracle.jdbc.implicitStatementCacheSize: 100  

application.properties

spring.datasource.hikari.data-source-properties.oracle.jdbc.implicitStatementCacheSize: 100 

您可能还对statement fetch size 感兴趣,但这种优化通常单独应用于每个语句。

【讨论】:

嗨@Karol,谢谢。我将如何使用 application.properties 文件而不是 application.yml 文件来改写这些属性?

以上是关于Oracle JDBC 优化:在 Spring 引导应用程序中启用 PreparedStatement 缓存的主要内容,如果未能解决你的问题,请参考以下文章

Spring 应用程序无法加载 JDBC 驱动程序类 [oracle.jdbc.driver.OracleDriver]

Spring JDBC 无法加载 JDBC 驱动程序类 [oracle.jdbc.driver.OracleDriver]

在某些参数类型是用户定义的情况下,如何使用 JDBC/Spring 调用 Oracle 存储过程?

使用 Spring Boot 和 Spring JDBC 在 oracle 中设置默认模式 = SOMETHING

在Spring中配置jdbc为啥不能用$问题

Spring Tool Suite - ClassNotFoundException:oracle.jdbc.driver.OracleDriver