CLOVER🍀

That was when it all began.

Database Riderで、外部キーを大量に使っているデータベースを対象にすると実行が遅くなるという話

これは、なにをしたくて書いたもの?

Javaでデータベースを使うテストで、Database Riderが便利なのでちょいちょいと使うのですが。

外部キーをたくさん使っていると実行が遅くなるという問題に悩まされたことがあったので、メモしておきます。

@DataSetのuseSequenceFiltering

Database Riderは、テストメソッドに@DataSetアノテーションを指定することでテスト実行前にデータのセットアップができます。

Database Rider / Rider Core / Configuration / DataSet Configuration

@DataSetアノテーションにはuseSequenceFilteringという属性があり、こちらをtrueにすることでテーブル間の依存関係を調べて
データを正しい順番で登録してくれます。

https://github.com/database-rider/database-rider/blob/1.41.0/rider-core/src/main/java/com/github/database/rider/core/dataset/DataSetExecutorImpl.java#L319-L328

https://github.com/database-rider/database-rider/blob/1.41.0/rider-core/src/main/java/com/github/database/rider/core/dataset/DataSetExecutorImpl.java#L148-L153

この機能は外部キーを使用している場合、データの登録順をテーブル間の依存関係を調べて明示的に指示しなくていいので便利です。
デフォルトで有効(true)になっています。

機能そのものは、DbUnitのもののようです。

なのですが、外部キーを使ったテーブルが多くなってくると実行速度が気になってきます。

issueが作成されたこともあるようです。

Slow Sequence Filtering on real database · Issue #242 · database-rider/database-rider · GitHub

テーブル間の依存関係を解析する機能はメモリー上にキャッシュされるので、テスト全体で実行される回数は少なくなります。

https://github.com/database-rider/database-rider/blob/1.41.0/rider-core/src/main/java/com/github/database/rider/core/api/dataset/RiderSequenceFilter.java#L153-L195

なのですが、IDE上でテストメソッドを実行する時などはキャッシュがないので、都度この負担が見えるようになります。

この挙動をちょっと確認しておきましょう。ソースコードの作成にはSpring Bootを使うことにします。

環境

今回の環境はこちら。

$ java --version
openjdk 21.0.1 2023-10-17
OpenJDK Runtime Environment (build 21.0.1+12-Ubuntu-222.04)
OpenJDK 64-Bit Server VM (build 21.0.1+12-Ubuntu-222.04, mixed mode, sharing)


$ mvn --version
Apache Maven 3.9.6 (bc0240f3c744dd6b6ec2920b3cd08dcc295161ae)
Maven home: $HOME/.sdkman/candidates/maven/current
Java version: 21.0.1, vendor: Private Build, runtime: /usr/lib/jvm/java-21-openjdk-amd64
Default locale: ja_JP, platform encoding: UTF-8
OS name: "linux", version: "5.15.0-91-generic", arch: "amd64", family: "unix"

データベースにはMySQLを使用しました。172.17.0.2で動作しているものとします。

 MySQL  localhost:3306 ssl  practice  SQL > select version();
+-----------+
| version() |
+-----------+
| 8.0.35    |
+-----------+
1 row in set (0.0011 sec)

Spring Bootプロジェクトを作成し、Database Riderへの依存関係を加える

まずはSpring Bootプロジェクトを作成します。依存関係にはjdbc、mysqlを追加しました。

$ curl -s https://start.spring.io/starter.tgz \
  -d bootVersion=3.2.1 \
  -d javaVersion=21 \
  -d type=maven-project \
  -d name=database-rider-resolve-table-dependencies \
  -d groupId=org.littlewings \
  -d artifactId=database-rider-resolve-table-dependencies \
  -d version=0.0.1-SNAPSHOT \
  -d packageName=org.littlewings.spring.dbrider \
  -d dependencies=jdbc,mysql \
  -d baseDir=database-rider-resolve-table-dependencies | tar zxvf -

作成されたプロジェクト内へ移動。

$ cd database-rider-resolve-table-dependencies

Maven依存関係など。

        <parent>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>3.2.1</version>
                <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>org.littlewings</groupId>
        <artifactId>database-rider-resolve-table-dependencies</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>database-rider-resolve-table-dependencies</name>
        <description>Demo project for Spring Boot</description>
        <properties>
                <java.version>21</java.version>
        </properties>
        <dependencies>
                <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-jdbc</artifactId>
                </dependency>

                <dependency>
                        <groupId>com.mysql</groupId>
                        <artifactId>mysql-connector-j</artifactId>
                        <scope>runtime</scope>
                </dependency>
                <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-test</artifactId>
                        <scope>test</scope>
                </dependency>
        </dependencies>

        <build>
                <plugins>
                        <plugin>
                                <groupId>org.springframework.boot</groupId>
                                <artifactId>spring-boot-maven-plugin</artifactId>
                        </plugin>
                </plugins>
        </build>

生成されたソースコードは削除しておきます。

$ rm src/main/java/org/littlewings/spring/dbrider/DatabaseRiderResolveTableDependenciesApplication.java src/test/java/org/littlewings/spring/dbrider/DatabaseRiderResolveTableDependenciesApplicationTests.java

そして、pom.xmlにはSpring向けのDatabase Rider(rider-spring)への依存関係を追加。

        <dependencies>
                <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-jdbc</artifactId>
                </dependency>

                <dependency>
                        <groupId>com.mysql</groupId>
                        <artifactId>mysql-connector-j</artifactId>
                        <scope>runtime</scope>
                </dependency>
                <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-test</artifactId>
                        <scope>test</scope>
                </dependency>
                <dependency>
                        <groupId>com.github.database-rider</groupId>
                        <artifactId>rider-spring</artifactId>
                        <version>1.41.0</version>
                        <scope>test</scope>
                </dependency>
        </dependencies>

今回はテストだけ実行できればいいので、@SpringBootApplicationだけを付与したダミーのクラスを作成しておきました。

src/main/java/org/littlewings/spring/dbrider/App.java

package org.littlewings.spring.dbrider;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {
}

application.propertiesはこのように設定。

src/main/resources/application.properties

spring.datasource.url=jdbc:mysql://172.17.0.2:3306/practice?characterEncoding=utf-8&connectionCollation=utf8mb4_0900_bin
spring.datasource.username=kazuhira
spring.datasource.password=password

dbunit.ymlも作成しました。

src/test/resources/dbunit.yml

cacheConnection: false
properties:
  caseSensitiveTableNames: true

外部キーを定義したテーブルを大量に作成して実行してみる

では、外部キーを定義したテーブルをたくさん作って、@DataSetのuseSequenceFilteringのtrue/falseでDatabase Riderの挙動が
どのように変わるのか見てみましょう。

以下のようなスクリプトでDDLを生成するようにしました。

create_table.py

import sys

table_num = int(sys.argv[1])

for i in range(table_num):
    num = i + 1

    if num == 1:
        print(f"""create table t{num} (
    id varchar(10),
    primary key(id)
);
        """)

        continue

    print(f"""create table t{num} (
    id varchar(10),
    t{num-1}_id varchar(10),
    primary key(id),
    foreign key(t{num-1}_id) references t{num-1}(id) on delete no action on update no action
);
          """)

引数で3を指定すると、こんな結果になります。

$ python3 create_table.py 3
create table t1 (
    id varchar(10),
    primary key(id)
);

create table t2 (
    id varchar(10),
    t1_id varchar(10),
    primary key(id),
    foreign key(t1_id) references t1(id) on delete no action on update no action
);

create table t3 (
    id varchar(10),
    t2_id varchar(10),
    primary key(id),
    foreign key(t2_id) references t2(id) on delete no action on update no action
);

今回は500を指定して、テーブルを作成しました。

$ python3 create_table.py 500

MySQL側での結果。

  MySQL  localhost:3306 ssl  practice  SQL > show tables;
+--------------------+
| Tables_in_practice |
+--------------------+
| t1                 |
| t10                |
| t100               |
| t101               |
| t102               |
| t103               |
| t104               |
| t105               |
| t106               |
| t107               |
| t108               |
| t109               |
| t11                |
| t110               |
| t111               |
| t112               |
| t113               |
| t114               |
| t115               |
| t116               |
| t117               |
| t118               |
| t119               |
| t12                |
| t120               |
| t121               |
| t122               |
| t123               |
| t124               |
| t125               |
| t126               |
| t127               |
| t128               |
| t129               |
| t13                |
| t130               |
| t131               |
| t132               |
| t133               |
| t134               |
| t135               |
| t136               |
| t137               |
| t138               |
| t139               |
| t14                |
| t140               |
| t141               |
| t142               |
| t143               |
| t144               |
| t145               |
| t146               |
| t147               |
| t148               |
| t149               |
| t15                |
| t150               |
| t151               |
| t152               |
| t153               |
| t154               |
| t155               |
| t156               |
| t157               |
| t158               |
| t159               |
| t16                |
| t160               |
| t161               |
| t162               |
| t163               |
| t164               |
| t165               |
| t166               |
| t167               |
| t168               |
| t169               |
| t17                |
| t170               |
| t171               |
| t172               |
| t173               |
| t174               |
| t175               |
| t176               |
| t177               |
| t178               |
| t179               |
| t18                |
| t180               |
| t181               |
| t182               |
| t183               |
| t184               |
| t185               |
| t186               |
| t187               |
| t188               |
| t189               |
| t19                |
| t190               |
| t191               |
| t192               |
| t193               |
| t194               |
| t195               |
| t196               |
| t197               |
| t198               |
| t199               |
| t2                 |
| t20                |
| t200               |
| t201               |
| t202               |
| t203               |
| t204               |
| t205               |
| t206               |
| t207               |
| t208               |
| t209               |
| t21                |
| t210               |
| t211               |
| t212               |
| t213               |
| t214               |
| t215               |
| t216               |
| t217               |
| t218               |
| t219               |
| t22                |
| t220               |
| t221               |
| t222               |
| t223               |
| t224               |
| t225               |
| t226               |
| t227               |
| t228               |
| t229               |
| t23                |
| t230               |
| t231               |
| t232               |
| t233               |
| t234               |
| t235               |
| t236               |
| t237               |
| t238               |
| t239               |
| t24                |
| t240               |
| t241               |
| t242               |
| t243               |
| t244               |
| t245               |
| t246               |
| t247               |
| t248               |
| t249               |
| t25                |
| t250               |
| t251               |
| t252               |
| t253               |
| t254               |
| t255               |
| t256               |
| t257               |
| t258               |
| t259               |
| t26                |
| t260               |
| t261               |
| t262               |
| t263               |
| t264               |
| t265               |
| t266               |
| t267               |
| t268               |
| t269               |
| t27                |
| t270               |
| t271               |
| t272               |
| t273               |
| t274               |
| t275               |
| t276               |
| t277               |
| t278               |
| t279               |
| t28                |
| t280               |
| t281               |
| t282               |
| t283               |
| t284               |
| t285               |
| t286               |
| t287               |
| t288               |
| t289               |
| t29                |
| t290               |
| t291               |
| t292               |
| t293               |
| t294               |
| t295               |
| t296               |
| t297               |
| t298               |
| t299               |
| t3                 |
| t30                |
| t300               |
| t301               |
| t302               |
| t303               |
| t304               |
| t305               |
| t306               |
| t307               |
| t308               |
| t309               |
| t31                |
| t310               |
| t311               |
| t312               |
| t313               |
| t314               |
| t315               |
| t316               |
| t317               |
| t318               |
| t319               |
| t32                |
| t320               |
| t321               |
| t322               |
| t323               |
| t324               |
| t325               |
| t326               |
| t327               |
| t328               |
| t329               |
| t33                |
| t330               |
| t331               |
| t332               |
| t333               |
| t334               |
| t335               |
| t336               |
| t337               |
| t338               |
| t339               |
| t34                |
| t340               |
| t341               |
| t342               |
| t343               |
| t344               |
| t345               |
| t346               |
| t347               |
| t348               |
| t349               |
| t35                |
| t350               |
| t351               |
| t352               |
| t353               |
| t354               |
| t355               |
| t356               |
| t357               |
| t358               |
| t359               |
| t36                |
| t360               |
| t361               |
| t362               |
| t363               |
| t364               |
| t365               |
| t366               |
| t367               |
| t368               |
| t369               |
| t37                |
| t370               |
| t371               |
| t372               |
| t373               |
| t374               |
| t375               |
| t376               |
| t377               |
| t378               |
| t379               |
| t38                |
| t380               |
| t381               |
| t382               |
| t383               |
| t384               |
| t385               |
| t386               |
| t387               |
| t388               |
| t389               |
| t39                |
| t390               |
| t391               |
| t392               |
| t393               |
| t394               |
| t395               |
| t396               |
| t397               |
| t398               |
| t399               |
| t4                 |
| t40                |
| t400               |
| t401               |
| t402               |
| t403               |
| t404               |
| t405               |
| t406               |
| t407               |
| t408               |
| t409               |
| t41                |
| t410               |
| t411               |
| t412               |
| t413               |
| t414               |
| t415               |
| t416               |
| t417               |
| t418               |
| t419               |
| t42                |
| t420               |
| t421               |
| t422               |
| t423               |
| t424               |
| t425               |
| t426               |
| t427               |
| t428               |
| t429               |
| t43                |
| t430               |
| t431               |
| t432               |
| t433               |
| t434               |
| t435               |
| t436               |
| t437               |
| t438               |
| t439               |
| t44                |
| t440               |
| t441               |
| t442               |
| t443               |
| t444               |
| t445               |
| t446               |
| t447               |
| t448               |
| t449               |
| t45                |
| t450               |
| t451               |
| t452               |
| t453               |
| t454               |
| t455               |
| t456               |
| t457               |
| t458               |
| t459               |
| t46                |
| t460               |
| t461               |
| t462               |
| t463               |
| t464               |
| t465               |
| t466               |
| t467               |
| t468               |
| t469               |
| t47                |
| t470               |
| t471               |
| t472               |
| t473               |
| t474               |
| t475               |
| t476               |
| t477               |
| t478               |
| t479               |
| t48                |
| t480               |
| t481               |
| t482               |
| t483               |
| t484               |
| t485               |
| t486               |
| t487               |
| t488               |
| t489               |
| t49                |
| t490               |
| t491               |
| t492               |
| t493               |
| t494               |
| t495               |
| t496               |
| t497               |
| t498               |
| t499               |
| t5                 |
| t50                |
| t500               |
| t51                |
| t52                |
| t53                |
| t54                |
| t55                |
| t56                |
| t57                |
| t58                |
| t59                |
| t6                 |
| t60                |
| t61                |
| t62                |
| t63                |
| t64                |
| t65                |
| t66                |
| t67                |
| t68                |
| t69                |
| t7                 |
| t70                |
| t71                |
| t72                |
| t73                |
| t74                |
| t75                |
| t76                |
| t77                |
| t78                |
| t79                |
| t8                 |
| t80                |
| t81                |
| t82                |
| t83                |
| t84                |
| t85                |
| t86                |
| t87                |
| t88                |
| t89                |
| t9                 |
| t90                |
| t91                |
| t92                |
| t93                |
| t94                |
| t95                |
| t96                |
| t97                |
| t98                |
| t99                |
+--------------------+
500 rows in set (0.0309 sec)

次は、テストを作成していきます。

まずはデータセットを用意。

src/test/resources/org/littlewings/spring/dbrider/dataset.yml

t1:
  - id: 0000100001
  - id: 0000100002
  - id: 0000100003
  - id: 0000100004
  - id: 0000100005
t2:
  - id: 0000200001
    t1_id: 0000100001
  - id: 0000200002
    t1_id: 0000100002
  - id: 0000200003
    t1_id: 0000100003
  - id: 0000200004
    t1_id: 0000100004

このデータセットは、@DataSetのuseSequenceFilteringの値に関わらず同じものを使います。

useSequenceFilteringをtrueにしたテストを用意。実行時間だけが見たいので、テストの中身は空です。

src/test/java/org/littlewings/spring/dbrider/DatabaseRiderUseSequenceFilteringTest.java

package org.littlewings.spring.dbrider;

import com.github.database.rider.core.api.dataset.DataSet;
import com.github.database.rider.spring.api.DBRider;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;

@DBRider
@SpringBootTest
class DatabaseRiderUseSequenceFilteringTest {
    @DataSet(
            value = "org/littlewings/spring/dbrider/dataset.yml",
            useSequenceFiltering = true  // default
    )
    @Transactional
    @Test
    void test() {
        // dummy
    }
}

繰り返しになりますが、useSequenceFilteringはデフォルトでtrueなので、明示的に指定なくても同じ状態になります。

このテストクラスを実行してみます。

$ mvn test -Dtest=DatabaseRiderUseSequenceFilteringTest

すると、以下の表示が出たところで動作が止まります。

2024-01-13T19:45:50.014+09:00  INFO 26309 --- [           main] c.g.d.r.c.dataset.DataSetExecutorImpl    : DBUnit configuration for dataset executor 'default':cacheConnection: false
cacheTableNames: true
caseInsensitiveStrategy: UPPERCASE
columnSensing: false
leakHunter: false
mergeDataSets: false
mergingStrategy: METHOD
disableSequenceFiltering: false
alwaysCleanBefore: false
alwaysCleanAfter: false
raiseExceptionOnCleanUp: false
disablePKCheckFor: com.github.database.rider.core.configuration.DBUnitConfig@e640772f
schema:
tableType: [TABLE]
allowEmptyFields: false
fetchSize: 100
qualifiedTableNames: false
prologTimeout: 1000
batchSize: 100
batchedStatements: false
caseSensitiveTableNames: true
replacers: [com.github.database.rider.core.replacers.DateTimeReplacer@7e0986c9, com.github.database.rider.core.replacers.UnixTimestampReplacer@1377b1a0, com.github.database.rider.core.replacers.NullReplacer@48cf8414]

しばらく待つと動き始め、自分の環境では1分近くかかってテストが終了しました。

[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 51.51 s -- in org.littlewings.spring.dbrider.DatabaseRiderUseSequenceFilteringTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  56.425 s
[INFO] Finished at: 2024-01-13T19:46:39+09:00
[INFO] ------------------------------------------------------------------------

この止まっている時にスレッドダンプを取ると、こんな感じになっていることが確認できます。

        at com.mysql.cj.jdbc.DatabaseMetaDataUsingInfoSchema.executeMetadataQuery(DatabaseMetaDataUsingInfoSchema.java:71)
        at com.mysql.cj.jdbc.DatabaseMetaDataUsingInfoSchema.getExportedKeys(DatabaseMetaDataUsingInfoSchema.java:404)
        at com.zaxxer.hikari.pool.ProxyDatabaseMetaData.getExportedKeys(ProxyDatabaseMetaData.java:177)
        at com.zaxxer.hikari.pool.HikariProxyDatabaseMetaData.getExportedKeys(HikariProxyDatabaseMetaData.java)
        at org.dbunit.database.search.AbstractMetaDataBasedSearchCallback.getNodes(AbstractMetaDataBasedSearchCallback.java:194)
        at org.dbunit.database.search.AbstractMetaDataBasedSearchCallback.getNodes(AbstractMetaDataBasedSearchCallback.java:149)
        at org.dbunit.database.search.AbstractMetaDataBasedSearchCallback.getNodesFromExportedKeys(AbstractMetaDataBasedSearchCallback.java:119)
        at org.dbunit.database.search.ExportedKeysSearchCallback.getEdges(ExportedKeysSearchCallback.java:54)
        at org.dbunit.util.search.DepthFirstSearch.reverseSearch(DepthFirstSearch.java:264)
        at org.dbunit.util.search.DepthFirstSearch.reverseSearch(DepthFirstSearch.java:273)
        at org.dbunit.util.search.DepthFirstSearch.reverseSearch(DepthFirstSearch.java:273)

    〜省略〜

        at org.dbunit.util.search.DepthFirstSearch.reverseSearch(DepthFirstSearch.java:273)
        at org.dbunit.util.search.DepthFirstSearch.reverseSearch(DepthFirstSearch.java:273)
        at org.dbunit.util.search.DepthFirstSearch.reverseSearch(DepthFirstSearch.java:273)
        at org.dbunit.util.search.DepthFirstSearch.search(DepthFirstSearch.java:148)
        at org.dbunit.util.search.DepthFirstSearch.search(DepthFirstSearch.java:104)
        at org.dbunit.database.search.TablesDependencyHelper.getDirectDependsOnTables(TablesDependencyHelper.java:232)
        at com.github.database.rider.core.api.dataset.RiderSequenceFilter.getDependencyInfo(RiderSequenceFilter.java:183)
        at com.github.database.rider.core.api.dataset.RiderSequenceFilter.sortTableNames(RiderSequenceFilter.java:68)
        at com.github.database.rider.core.api.dataset.RiderSequenceFilter.<init>(RiderSequenceFilter.java:34)
        at com.github.database.rider.core.dataset.DataSetExecutorImpl.performSequenceFiltering(DataSetExecutorImpl.java:324)
        at com.github.database.rider.core.dataset.DataSetExecutorImpl.createDataSet(DataSetExecutorImpl.java:129)
        at com.github.database.rider.core.RiderRunner.runBeforeTest(RiderRunner.java:44)
        at com.github.database.rider.spring.DBRiderTestExecutionListener.beforeTestMethod(DBRiderTestExecutionListener.java:24)
        at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:320)
        at org.springframework.test.context.junit.jupiter.SpringExtension.beforeEach(SpringExtension.java:240)

    〜省略〜

このあたりが、テーブル間の依存関係を調べている処理です。

        at org.dbunit.database.search.TablesDependencyHelper.getDirectDependsOnTables(TablesDependencyHelper.java:232)
        at com.github.database.rider.core.api.dataset.RiderSequenceFilter.getDependencyInfo(RiderSequenceFilter.java:183)
        at com.github.database.rider.core.api.dataset.RiderSequenceFilter.sortTableNames(RiderSequenceFilter.java:68)
        at com.github.database.rider.core.api.dataset.RiderSequenceFilter.<init>(RiderSequenceFilter.java:34)
        at com.github.database.rider.core.dataset.DataSetExecutorImpl.performSequenceFiltering(DataSetExecutorImpl.java:324)

もうひとつ、useSequenceFilteringをfalseにしたテストを用意。

src/test/java/org/littlewings/spring/dbrider/DatabaseRiderDisableSequenceFilteringTest.java

package org.littlewings.spring.dbrider;

import com.github.database.rider.core.api.dataset.DataSet;
import com.github.database.rider.spring.api.DBRider;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;

@DBRider
@SpringBootTest
class DatabaseRiderDisableSequenceFilteringTest {
    @DataSet(
            value = "org/littlewings/spring/dbrider/dataset.yml",
            useSequenceFiltering = false,
            tableOrdering = {"t1", "t2"}
    )
    @Transactional
    @Test
    void test() {
        // dummy
    }
}

こちらはuseSequenceFilteringをfalseにしているので、tableOrderingも指定しています。

テストを実行してみます。

$ mvn test -Dtest=DatabaseRiderDisableSequenceFilteringTest

同じデータベースに対するテストですが、こちらはすぐに終わります。

[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.641 s -- in org.littlewings.spring.dbrider.DatabaseRiderDisableSequenceFilteringTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  4.562 s
[INFO] Finished at: 2024-01-13T19:48:59+09:00
[INFO] ------------------------------------------------------------------------

けっこう差が歴然と出ますね。

今回は単純なテーブル構造なので、わかりやすく差が出るところまでテーブルを作成(500個)しましたが、ちゃんとした開発で
外部キーを使うともっと複雑、複数のテーブルに外部キーを作成したりといろいろ入り組んだりすると思います。
そうすると、ここまでの数のテーブルに到達する前に、もっとわかりやすく速度劣化します。

おわりに

Database Riderで、useSequenceFilteringをtrueにしたまま外部キーを大量に使っているデータベースを対象にすると実行が遅くなる
ということを見てみました。

この状態になるとテストをIDE上で実行するのがだんだん嫌になってくるので、useSequenceFilteringをfalseにしてtableOrderingを
指定するのが良いと思います。

一方で、tableOrderingを指定するということは依存関係にしたがった順で書いていく必要があるので、面倒なのですが…。

というわけで、その対応案も考えてみました。

Spring Test × Database Riderで、データを作成する時にテーブル間の依存関係を記録する - CLOVER🍀