batchInsertを使っているのに遅い気がする
気がするというかかなり遅かった。
たかだか10000件のInsertが10秒だって?
うわっ…私のDB、遅すぎ…?
というわけで少しこの問題を調べてみた。
確認:PostgreSQLのreWriteBatchedInsertsをTrueにしているか?
Database.connect(PGSimpleDataSource().apply {
setURL("jdbc:postgresql://localhost:5432/postgres")
user = "pguser"
password = "pgpass"
reWriteBatchedInserts = true // ← この野郎をTrueにしまくる
})
ドライバとExposedのバージョンを確認する
postgresqlのバージョンは**>=42.2.2**であればinsert on conflict
の不具合が解消されているという事で、まあ最新ならよろし。
問題はexposedのバージョンで、下記のようにexposed-coreではなく、exposedの最新implementation 'org.jetbrains.exposed:exposed:0.17.13'
を使っていた事に問題があった。よってこれを現在最新の以下のバージョンに書き換えた。
dependencies {
implementation 'org.postgresql:postgresql:42.2.23'
implementation 'org.jetbrains.exposed:exposed-core:0.32.1'
runtimeOnly 'org.jetbrains.exposed:exposed-jdbc:0.32.1'
}
結論をいうと10倍以上早くなった……が
reWriteBatchedInsertsをfalseにしてもさほど結果が変わらないという謎が実は残っている。あれ? 結局バージョンを上げただけなのって思うかも知れないが、そんだけの事で2時間ぐらいハマってしまった。
ソース上の変更点
バージョンを上げるとbatchInsertが例外を吐くようになった。
プライマリキーのUUIDのデフォルトをuuid_generate_v4()
としているが、デフォルトは使えなくなっている。全ての列に値を設定してやると良いようだ。
object HorseRaceResultTable: Table() {
val id = uuid("id")
val raceName = text("レース名")
val winner = text("勝ち馬")
val reserve = text("reserve")
}
fun main() {
Database.connect(PGSimpleDataSource().apply {
setURL("jdbc:postgresql://localhost:5432/postgres")
user = "pguser"
password = "pgpass"
reWriteBatchedInserts = true
})
val values = mutableListOf<Pair<String,String>>()
values.add("宝塚記念" to "クロノジェネシス")
values.add("安田記念" to "ダノンキングリー")
values.add("東京優駿" to "シャフリヤール")
measureTimeMillis { // ← こいつは計測のため
transaction {
HorseRaceResultTable.batchInsert(values) { // ← batchInsertを使う
this[HorseRaceResultTable.id] = UUID.randomUUID() // ← UUIDも自分で設定
this[HorseRaceResultTable.raceName] = it.first
this[HorseRaceResultTable.winner] = it.second
this[HorseRaceResultTable.reserve] = "" // ← 使わなくてもちゃんと設定
}
}
}.let { println("insert time is $it ms") }
}
MySQLだったらrewriteBatchedStatements=trueでサクッと行くらしい
でもPostgreSQLはハマってる人結構たくさんいたんだよね。速くなったから使えてるんだと思うんだけど。
あと意外と重要なのがログレベルをDEBGUGにしてたらExposedがSQL全出力しちゃうから大量データのInsertではここも気をつけましょうネ。