🐾
Mybatisの1stレベルキャッシュとキャッシュなしの速度比較
概要
Mybatisの1stレベルキャッシュが使用される場合と使用されない場合の速度比較を行います。クエリを実行するステートメントを10万回呼び出して速度比較を行った結果、以下のような結果が得られました。
1stレベルキャッシュ | 実行時間 |
---|---|
あり | 0.469892000 |
なし | 33.789556000 |
確認環境
- Java 21
- Spring Boot 3.4.1
- MyBatis Spring Boot Starter 3.0.4
- PostgreSQL 16.4
確認方法
1stレベルキャッシュを使用する場合、キャッシュを使用しない場合のそれぞれを計測し、キャッシュ使用時と未使用時の速度差を求めます。
依存関係
build.gradle.kts
dependencies {
implementation("org.springframework.boot:spring-boot-starter:3.4.1")
implementation("org.springframework.boot:spring-boot-starter-jdbc:3.4.1")
implementation("org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.4")
implementation("org.postgresql:postgresql:42.7.4")
}
データベース
テーブル定義
テーブル
Table "public.example"
Column | Type | Collation | Nullable | Default
--------+-----------------------+-----------+----------+---------
id | character varying(4) | | not null |
memo | character varying(50) | | |
データ
データ
Table "public.example"
id | memo
------+----------
0001 | example1
0002 | example2
1stレベルキャッシュの速度確認プログラム
構成
com.example
+- ExampleApplication.java
+- ExampleApplicationRunner.java
+- ExampleRepository.java
+- ExampleMapper.java
+- ExampleMapper.xml
ExampleApplication
はアプリケーションのエントリポイントです。
ExampleApplication.java
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ExampleApplication {
public static void main(String[] args) {
SpringApplication.run(ExampleApplication.class, args);
}
}
ExampleApplicationRunner
は ApplicationRunner
を実装します。このクラスがアプリケーション起動時に呼び出されます。
ExampleApplicationRunner.java
package com.example;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.time.Duration;
import java.time.LocalDateTime;
@Component
public class ExampleApplicationRunner implements ApplicationRunner {
private final Logger log = LoggerFactory.getLogger(ExampleApplicationRunner.class);
private ExampleRepository exampleRepository;
public ExampleApplicationRunner(ExampleRepository exampleRepository) {
this.exampleRepository = exampleRepository;
}
@Override
public void run(ApplicationArguments args) throws Exception {
LocalDateTime start = LocalDateTime.now();
exampleRepository.get();
LocalDateTime end = LocalDateTime.now();
Duration duration = Duration.between(start, end);
log.info("*** {}.{} ***", duration.getSeconds(), duration.getNano());
}
}
ExampleRepository
はデータソースへアクセスするためのクラスです。
ExampleRepository.java
package com.example;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
@Repository
public class ExampleRepository {
private final Logger log = LoggerFactory.getLogger(ExampleRepository.class);
private ExampleMapper exampleMapper;
public ExampleRepository(ExampleMapper exampleMapper) {
this.exampleMapper = exampleMapper;
}
@Transactional
public void get() {
for (int i = 0; i < 100000; i++) {
exampleMapper.get("0001");
}
}
}
ExampleMapper
ではデータベース操作に対応するメソッドを宣言します。
ExampleMapper.java
package com.example;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface ExampleMapper {
List<Map<String, Object>> get(@Param("id") String id);
}
ExampleMapper.xml
にクエリを記述します。
ExampleMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.example.ExampleMapper">
<select id="get" resultType="hashmap">
select * from example where id = #{id};
</select>
</mapper>
1stレベルキャッシュとキャッシュなしの速度確認結果
まずは1stレベルキャッシュ使用時の速度を確認します。
結果
com.example.ExampleApplicationRunner : *** 0.469892000 ***
次に application.properties
に mybatis.configuration.local-cache-scope=STATEMENT
を設定し、キャッシュなしの速度を確認します。
結果
com.example.ExampleApplicationRunner : *** 33.789556000 ***
Discussion