繁体   English   中英

Spring Boot JdbcTemplate - 禁用语句缓存?

[英]Spring Boot JdbcTemplate - disable statement cache?

我有一个 Spring Boot 后端,我使用 REST-API 与之通信。 此后端使用 Spring JdbcTemplate连接并在 PostgreSQL 数据库上执行查询。

我发现了一个问题,即一个请求在精确重复 10 次后变得明显变慢。 我已将问题缩小到使用JdbcTemplate从数据库中检索数据的代码部分。 更具体地说,问题出现在每个 tomcat 工作线程的第二次迭代中:

[nio-8080-exec-1] --- GET /myresource - Execution time 400 ms
[nio-8080-exec-2] --- GET /myresource - Execution time 300 ms
[nio-8080-exec-3] --- GET /myresource - Execution time 285 ms
...
[io-8080-exec-10] --- GET /myresource - Execution time 200 ms

现在每个 tomcat worker 已经接收并处理了一个请求,下一次这些 worker 中的一个接收到相同的请求,使用完全相同的查询,执行时间长 10-15 倍:

[nio-8080-exec-1] --- GET /myresource - Execution time 6000 ms
[nio-8080-exec-2] --- GET /myresource - Execution time 5500 ms
[nio-8080-exec-3] --- GET /myresource - Execution time 6700 ms

我尝试使用 psql 或 pgAdmin 运行相同的查询,但没有问题。 这让我相信JdbcTemplate以某种方式为每个工作人员缓存查询,第二次运行查询时缓存启动,由于某种原因它慢得多,但我不确定。 我也尝试将 tomcat 更改为 jetty/undertow,但在那里发生了同样的问题,所以我相信它一定与JdbcTemplate

有什么方法可以使用JdbcTemplate禁用这种类型的缓存,或者我还能做些什么来避免这种行为?

谢谢!

编辑:
我的应用程序.yaml:

spring:
    datasource:
        platform: postgres
        url: my-jdbc-url
        username: my-user
        password: my-password

代码根据请求中的参数动态创建带有 WHERE/AND 子句的查询,但相同的请求参数始终创建相同的查询。 代码:

public List<MyDatatype> runQuery(MyParams params) {
    String sql = createSqlFromParams(params);
    List<Object> params = createParamsList(params);
    return jdbcTemplate.query(sql, params.toArray(), myDatatypeRowMapper());
}

查询最终将如下所示(使用 postGIS 函数按坐标之间的距离排序):

SELECT * FROM my_table 
WHERE x IN [1,2,3] 
AND y BETWEEN 0 AND 1000
AND z BETWEEN 0 AND 500
ORDER BY geom <-> other_geom
LIMIT 1000;

编辑2:
根据@M.Deinum 的建议,添加
spring.datasource.hikari.data-source-properties.preparedStatementCacheQueries=0解决了这个问题!

假设您在 Spring Boot 中使用默认连接池 HikariCP,您可以使用spring.datasource.hikari.data-source-properties来提供额外的、特定于驱动程序的属性。

要禁用服务器准备preparedStatementCacheQueries 语句,您需要包含preparedStatementCacheQueries属性并将值设置为 0(默认值为 256)。

spring.datasource.hikari.data-source-properties.preparedStatementCacheQueries=0

这将禁用整个缓存并可能影响应用程序的不同区域。

此处此处的这些相关问题似乎暗示您可能想要检查磁盘、索引等,而不是禁用查询缓存。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM