パフォーマンス向上のため、PrepareStmtをtrueにした。
https://gorm.io/docs/performance.html#Caches-Prepared-Statement
これは標準パッケージの PrepareContext
の実行結果の sql.Stmt
をキャッシュしておいて、2回目以降の実行を速くする。
https://github.com/go-gorm/gorm/blob/206613868439c5ee7e62e116a46503eddf55a548/prepare_stmt.go#L68
これを有効にしたときにメモリリークが発生するようになったため、原因を調べた。
再現方法
以下のようなSQLを実行していた。
これの問題点は、 weight
の値ごとに異なるSQLが発行されることだった。
PrepareStmt: true のとき、GORMの実装では発行されたSQL文をキーにmap型の値にキャッシュされるため、 weight
の値がばらつくほどキャッシュされる量も増える。
これによってメモリリークが発生していた。
解決方法
解決方法は、ちゃんとprepared statementにすることだ。
- 単純なOrderには指定ができなかったので、clauseを使って生SQLを書く
First
を指定するとORDER BY <primary key>
で上書きされてしまったため、Limit(1).Find
にした