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));
}
我看到了
time: 17
time: 1
time: 0
time: 0
time: 1
...
那么,jdbc以某种方式缓存结果吗?为什么第一次这么慢,跟着这么快?
答案 0 :(得分:4)
这种行为有几种可能的原因,并不是非典型的:
正如khelwood在评论中所说:数据库经过优化,可以在访问后将表内容缓存在内存中。因此,在第二次调用时,数据库可能会在内存中找到数据,而不是从磁盘加载数据。
DataSource
的某些实现缓存连接,因此第二次调用createConnection()
不需要创建新连接(这是昂贵的),它只会重用旧连接。
第一次调用getConnection()
和createStatement()
时,JDBC驱动程序使用的许多类可能会在第二次循环中加载。
如果这样的循环经常运行,那么热点编译器也可以JIT编写你的Java代码,以便在一些循环之后运行得更快。
可能原因1和2对观察到的行为影响最大,因为只有200个循环可能不会出现原因4。