レスポンスタイムが影響するSpring bootアプリ開発時に、レコードをメモリに持たせるべきかJPAでゴリ押すか悩んでいる
SpringJPA, forEach, 拡張forのレスポンスタイム対決
あるリクエストを受けるとSpring JPA経由でDBに検索クエリ投げて値を得るという処理があった。
プログラムの性質上、レスポンスタイムを意識しないといけなかったので、EntityをfindAll()で取得したList<Entity>のBeanを作成し、拡張forかforEachで対象のEntityを検索するという処理のどれがいいかを考えた。
Entityを1000件用意して、1000件目(ぐらいに保持している)のデータを得るという処理を作って計測したところ以下の結果を得た。
実装方法 | 結果(msec) |
---|---|
JPA | 37 |
拡張for | 0 |
forEach | 1 |
当然、JPAがダントツで遅い。DBアクセスするので当然だ。
msec単位なので雑だが、forEachより拡張for文が一番性能が良かった。ほぼ変わらないけど、速さを意識するなら拡張for文のほうがよさそう。
プログラムはここでは省略してるのでちゃんとした結果はどこかで書きたいなぁ。
ListのBean作成戦術、実際に実装すると色々とデメリットも出てきた。
そもそもEntityへの追加や変更がないことが前提でBeanを組んでいるので、特定条件下のテスト実行のための登録や変更が発生するJUnitテストでは失敗が起きるようになった。
Beanは最初に作られることもあってBeforeAllとかでもうまく対処できなさそう。
TestConfigrationアノテーションやPrimaryアノテーションでBeanをオーバライドする手もあるが、私の実装では保守の観点など色々考えてやめることにした。
上記、後々考えて37msecって、JPAって案外クエリ遅い気がする。実装は結局性能重視でBean作成して使うようにした。
毎回if(bean.getId().equals(id))みたいなのするの超嫌だけど。
結局同じような問題に直面して、上の原因分からなくて困ってる、、、
私は間抜けなのでIndex annotation考慮してなかったのだが、それでも1000レコードで37msは遅いのではないかな。またIndex張って試してみます。