for (int i = 0; i < 200; ++i) {
long start = System.currentTimeMillis();
Connection conn = dataSource.getConnection();
ResultSet rs = conn.createStatement().executeQuery("SELECT id FROM accounts LIMIT 1");
rs.next();
long id = rs.getLong("id");
conn.close();
long end = System.currentTimeMillis();
System.out.println("time: " + (end - start));
}
Run Code Online (Sandbox Code Playgroud)
我看到
time: 17
time: 1
time: 0
time: 0
time: 1
...
Run Code Online (Sandbox Code Playgroud)
那么,jdbc 是否以某种方式缓存了结果?为什么第一次那么慢而后面那么快?
小智 5
这种行为有多种可能的原因,并且并非不典型:
正如 khelwood 在评论中所说:数据库经过优化,可在访问表内容后将其缓存在其内存中。因此,第二次调用时,数据库可能会在内存中找到数据,而不必从磁盘加载它。
DataSource缓存连接的一些实现,因此第二次调用createConnection()不需要创建新连接(这是昂贵的),它只会重用旧连接。
在第一次调用时getConnection(),createStatement()JDBC 驱动程序使用的许多类可能会在那时被加载,这在第二个循环中是不必要的。
如果这样的循环运行非常频繁,Hotspot Compiler 也可能对您的 Java 代码进行了 JIT,以便它在一些循环后运行得更快。
可能原因 1 和 2 对观察到的行为影响最大,原因 4 可能不会在仅 200 个循环时出现。