【jOOQ】UUIDを大量指定する際の省メモリ化【PostgreSQL】

状況

大量のUUIDを指定したin句を発行する際に、メモリ消費量が問題になりました。
見たところ、jOOQではUUID1件当たりcast('b81b8735-6ac8-4b0b-a969-658e70425616' as uuid)みたいな形のクエリになってしまうことが原因のようでした。

対処

応急処置として、以下2点を満たす省メモリ化されたin句を発行するためのカスタム実装を行いました。

  • cast文無し
  • UUIDのハイフン無し

サンプルコード

Kotlinかつ一部余計な処理が入ってますが、要するに${取得対象カラム} in (b81b87356ac84b0ba969658e70425616, ...)みたいな条件を生成しています。

private val hexFormat = HexFormat.of()

fun UUID.hyphenLessStr(): String = hexFormat.toHexDigits(this.mostSignificantBits) + hexFormat.toHexDigits(this.leastSignificantBits)

// jOOQの生成結果が基本nullableなため、Fieldの型パラメータはnullableにしている
fun <T> Field<UUID?>.reducedIn(args: Collection<T>, unbox: (T) -> UUID): Condition {
    val condStr = args.joinToString(prefix = "${this.qualifiedName} in (", separator = ",", postfix = ")") {
        // アプリ上メモリ消費量低減のため、普通のUUIDからハイフンを抜いた形式にしている
        // 参照: https://www.postgresql.org/docs/14/datatype-uuid.html
        "'${unbox(it).hyphenLessStr()}'"
    }

    return DSL.condition(condStr)
}

PostgreSQLのクエリにおけるUUID指定について

ハイフン無しでOKということは文章化されています。

www.postgresql.org