我有一臺運行 Spring Boot JPA Hibernate 的服務器。我正在使用 MySQL 資料庫(默認使用 InnoDb 引擎)。該實作從我在 Internet 上搜索的許多文章中汲取靈感。我已經實作了 REST API 來促進動態構建網站。我想將所有 API 請求記錄到日志(審計日志)中。所以當API被呼叫時,我將請求方法名稱和一些引數存盤到MySql中的審計日志表中。就在我從 API 回傳之前,我還通過更新相同的記錄來存盤回應。
當我使用 Web 應用程式客戶端和 Postman 發出 API 請求時,我正在查看 Hibernate 的代碼日志。我注意到對于每個 API,插入和更新平均需要 150 毫秒 - 200 毫秒。事實證明,這對于獲取很少資訊的 API 來說成本很高。
所以我想知道如何加快插入速度,以便我的插入/更新時間少于 10 -20 毫秒。
我的審核日志物體是
@Entity
@Table(name="auditlog")
public class AuditLog{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable = false, updatable = false)
@Temporal(TemporalType.TIMESTAMP)
@CreatedDate
private Date created_at;
@Column(nullable = false)
@Temporal(TemporalType.TIMESTAMP)
@LastModifiedDate
private Date updated_at;
@NotBlank
private String methodName;
private String param1;
// Text field with private information like password masked
@Column(length = 65535, columnDefinition = "text")
private String request;
// Text field
@Column(length = 65535, columnDefinition = "text")
private String response;
private Integer result;
... // getters and setters
}
我的 AuditLogRepository 是:
public interface AuditLogRepository extends JpaRepository<AuditLog, Long>{
}
在我的 REST API 控制器中,我正在執行以下操作
...
AuditLog logEntry = new AuditLog();
// set all the values except generated ones like id, created_at and updated_at
logEntry.setMethodName(...);
logEntry.setParam1(...);
logEntry.setRequest(...);
// Save into the table using autowired repoitory
auditLogRepoitory.saveAndFlush(logEntry);
// ... do the operation of the API
// Update the logEntry
logEntry.setResult(...);
logEntry.setResponse(...);
auditLogRepoitory.saveAndFlush(logEntry);
...
請幫助我改進表格的插入和更新。或者請幫助改進代碼,以便我可以更快地回應 API。
謝謝,斯里普拉德
uj5u.com熱心網友回復:
第一個提示
如果你想加速插入/更新,不要使用 JpaRepository.save 方法(注意 saveAndFlush() 內部呼叫 save 方法)。
因為 JpaRepository.save 內部選擇物體是為了知道物體是新的還是資料庫中存在的。這是 jpaRepository.save 的默認實作:
@Transactional
public <S extends T> S save(S entity) {
Assert.notNull(entity, "Entity must not be null.");
if (this.entityInformation.isNew(entity)) {
this.em.persist(entity);
return entity;
} else {
return this.em.merge(entity);
}
}
我認為使用 jdbcTemplate 是最好的選擇。
第二個技巧
在考慮優化插入時,考慮進行批量插入可能很有用。根據mysql檔案網站,插入一行所需的時間由以下因素決定,其中數字表示大致比例:
- 連接: (3)
- 向服務器發送查詢:(2)
- 決議查詢:(2)
- 插入行:(1 × 行大小)
- 插入索引:(1 × 索引數)
- 閉幕式:(1)
因此,您可以輕松了解批量插入如何幫助您提高插入速度。
第三個技巧
您可能需要按照此stackeroverflow anwser 中的說明調整 mysql 實體設定
其他選項
確保您選擇了正確的 ID 生成策略,如此處所述https://dzone.com/articles/spring-boot-boost-jpa-bulk-insert-performance-by-100x
uj5u.com熱心網友回復:
如果您的框架允許,請執行
START TRANSACTION
在構建頁面和存盤審計的開始。和
COMMIT
在最后。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/380106.html
