我想比较Spring数据和JDBI的性能 我使用了以下版本
Spring Boot 2.2.4.RELEASE
vs
JDBI 3.13.0
测试非常简单,从管理表中选择*并转换为管理对象列表
这是相关详细信息
带有弹簧靴
public interface AdminService extends JpaRepository<Admin, Integer> {
}
和JDBI
public List<Admin> getAdmins() {
String sql = "Select admin_id as adminId, username from admins";
Handle handle = null;
try {
handle = Sql2oConnection.getInstance().getJdbi().open();
return handle.createQuery(sql).mapToBean(Admin.class).list();
}catch(Exception ex) {
log.error("Could not select admins from admins: {}", ex.getMessage(), ex );
return null;
} finally {
handle.close();
}
}
使用junit 5执行测试类
@Test
@DisplayName("How long does it take to run 1000 queries")
public void loadAdminTable() {
System.out.println("Running load test");
Instant start = Instant.now();
for(int i= 0;i<1000;i++) {
adminService.getAdmins(); // for spring its findAll()
for(Admin admin: admins) {
if(admin.getAdminId() == 654) {
System.out.println("just to simulate work with the data");
}
}
}
Instant end = Instant.now();
Duration duration = Duration.between(start, end);
System.out.println("Total duration: " + duration.getSeconds());
}
我很震惊获得以下结果
春季数据:2秒 JDBI:59秒
知道我为什么得到这些结果吗?我期望JDBI更快
答案 0 :(得分:2)
问题在于,Spring有很好的理由为我们管理连接生命周期 在阅读了JDBI的文档之后
每次分配连接都会降低性能 然后发布。在上面的示例中,两个insertFullContact 操作从数据库中获取单独的连接对象 连接池。
我将JDBI测试的测试代码更改为以下
@Test
@DisplayName("How long does it take to run 1000 queries")
public void loadAdminTable() {
System.out.println("Running load test");
String sql = "Select admin_id as adminId, username from admins";
Handle handle = null;
handle = Sql2oConnection.getInstance().getJdbi().open();
Instant start = Instant.now();
for(int i= 0;i<1000;i++) {
List<Admin> admins = handle.createQuery(sql).mapToBean(Admin.class).list();
if(!admins.isEmpty()) {
for(Admin admin: admins) {
System.out.println(admin.getUsername());
}
}
}
handle.close();
Instant end = Instant.now();
Duration duration = Duration.between(start, end);
System.out.println("Total duration: " + duration.getSeconds());
}
这样,一次打开连接,查询运行1000次
最终结果是1秒
两倍于弹簧
答案 1 :(得分:1)
一方面,您似乎犯了一些基准测试的基本错误:
因此,您所看到的可能只是虚拟机不同优化的影响。 查看JMH,以提高基准。
使用外部资源进行基准测试特别困难,因为您需要控制的参数太多。 例如,一个大问题是,与数据库的连接是否实际上很慢,因为在大多数生产系统中,数据库至少实际上将位于不同的计算机上,很可能位于不同的硬件上。 在您的测试中也是这样吗?
假设您的结果是真实的,那么下一步就是调查多余的时间花在哪里。 我希望在执行SQL语句和通过网络获得结果上花费最多的时间。 因此,您应该检查实际上执行了哪些SQL语句。
这可能会为您提供一个可能的答案,即JPA正在执行很多延迟加载,甚至没有加载您真正需要的大多数。