[英]How to save @Lob data from spring in to a Postgres database?
[英]Benchmarking spring data vs JDBI in select from postgres Database
我想比較 Spring 數據與 JDBI 的性能我使用了以下版本
Spring Boot 2.2.4.RELEASE
對比
JDBI 3.13.0
測試相當簡單 select * 從 admin 表並轉換為 Admin object 列表
這是相關的細節
帶 spring 啟動
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 執行測試 class
@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());
}
我很震驚得到以下結果
Spring 數據:2 秒 JDBI:59 秒
知道為什么我得到這些結果嗎? 我期待 JDBI 更快
問題是 spring 為我們管理連接生命周期,並且在閱讀 JDBI 文檔后有充分的理由
每次分配和釋放連接時都會有性能損失。 在上面的示例中,兩個 insertFullContact 操作從數據庫連接池中獲取單獨的 Connection 對象。
我將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 秒
速度是 spring 的兩倍
一方面,您似乎在基准測試中犯了一些基本錯誤:
因此,您所看到的可能只是虛擬機不同優化的效果。 查看JMH以改進您的基准。
使用外部資源進行基准測試非常困難,因為您要控制的參數太多了。 一個大問題是,例如,與數據庫的連接是否真的很慢,因為在大多數生產系統中,數據庫至少虛擬地位於不同的機器上,很可能在不同的硬件上。 在你的測試中也是這樣嗎?
假設你的結果是真實的,下一步是調查額外的時間花在了哪里。 我預計大部分時間都花在執行 SQL 語句並通過網絡獲取結果上。 因此,您應該檢查實際執行了哪些 SQL 語句。
這可能會為您指出一個可能的答案,即 JPA 正在執行大量延遲加載,甚至還沒有加載您真正需要的大多數人。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.