Spring DAO - 使用 JdbcTemplate 的第一次查询需要更长的时间

Posted

技术标签:

【中文标题】Spring DAO - 使用 JdbcTemplate 的第一次查询需要更长的时间【英文标题】:Spring DAO - first query with JdbcTemplate takes much longer time 【发布时间】:2012-08-22 21:43:04 【问题描述】:

在我的应用程序中,我使用带有 DAO 模式的 Spring MVC 通过 JdbcTemplate 访问 MSSql 数据库。一切正常,但我注意到第一个查询比每个请求中的下一个查询花费的时间要长一些。

我写了一个简单的测试:

String sql = "SELECT 1";
for (int i = 0; i < 5; i++) 
    long startTime = System.currentTimeMillis();
    jdbcTemplate.queryForList(sql);
    logger.debug("query took: " + TimeHelper.showDuration(startTime));

结果是:

2012-08-28 12:55:07,665 | Start
2012-08-28 12:55:08,878 | query took: 424 milliseconds
2012-08-28 12:55:08,893 | query took: 15 milliseconds
2012-08-28 12:55:08,908 | query took: 14 milliseconds
2012-08-28 12:55:08,922 | query took: 14 milliseconds
2012-08-28 12:55:08,937 | query took: 14 milliseconds

我了解 Spring 正在执行一些活动来准备所有 bean。但是,如果对服务器的请求只执行 1 个查询,那么每个请求需要 424 毫秒。

我的问题是:这种行为可以吗?或者我的代码中可能存在一些错误?它是否可以在每次请求时 Spring 都需要这段时间进行初始化? (然后请求中的所有其他查询都会运行得很快)?或者我可以做一些启动初始化,然后在每个请求期间,第一个查询也需要 15 毫秒?

我的配置如下:

datasource: class="org.apache.commons.dbcp.BasicDataSource"

dao 被注入到测试类中:

@Resource(name="testDao")  
private TestDao testDao;  

我使用基于注释的方法。测试类和 DAO 不使用 @Transaction。

编辑: 我也尝试配置 initialSize 但这没有帮助,(initialSize=2 需要 800 毫秒,initialSize=1 需要 400 毫秒 - 每个请求)。

我不明白为什么每个请求都需要 400 毫秒,而可能需要 15 毫秒。 Spring 似乎有些开销。 :(

【问题讨论】:

【参考方案1】:

您的 DataSource 是一个连接池。第一个查询需要连接。后续查询重用该连接。您可以将 dbcp 配置为预先创建一些连接,也可以在应用启动后立即手动连接和释放。

【讨论】:

我尝试将 DBCP 配置为 initialSize = 2(此数字越大,所需的时间越长),但这种行为在每次请求时都会重复,所以如果我在启动时连接它将无济于事,它似乎请求完成后所有连接都关闭了,还是AOP有问题(调用jdbcTemplate.queryForList时弹簧搜索一些bean)? 多年前我测量的 JDBC 时间:建立 tcp 连接 ~700ms;准备语句 ~70ms;执行语句~10ms。所以这听起来确实像是建立连接的时机。我会看看连接池配置。查看 v$session 以了解如何以及何时建立 jdbc 连接。如果从 1 连接更改为 2 连接将时间从 400 毫秒更改为 800 毫秒,那么这是另一个强指针。【参考方案2】:

看看javadoc 和source。 getExceptionTranslator() 可能涉及一些设置工作。也许您可以使用 lazy-init 参数控制该工作何时发生。

【讨论】:

【参考方案3】:

我检查了连接池及其连接(initialSize)是在第一次调用时在需要连接时创建的,然后它在所有请求中被重用,这就是它应该如何工作的:),我还注意到 400 毫秒的时间当同时有多个请求时较低(约 100 毫秒)。我认为最初较长时间的原因是因为建立了 John Watts 提到的 TCP 连接,或者是因为一些 Spring 后台管理。

【讨论】:

以上是关于Spring DAO - 使用 JdbcTemplate 的第一次查询需要更长的时间的主要内容,如果未能解决你的问题,请参考以下文章

spring javaconfig druidsource

8 -- 深入使用Spring -- 8...1 Spring提供的DAO支持

spring中JDBCTemplate的简单应用

Spring Boot2 系列教程 | 使用 JdbcTemplates 访问 Mysql

spring配置连接池和dao使用jdbcTemplate

如何使用 Spring Security 对 Spring 4 DAO 方法进行单元测试?