カルテ表示高速化
開院当初からずっと通院して下さっている,DocumentModel 120件超えの患者さんがいらっしゃるのだが,先日,この患者さんのカルテで SelectAll して検索しようとしたところ,全てのカルテを読み込むのに 20秒以上かかってしまった。
調べてみたら,RemoteKarteServiceImpl#getDocuments(List
そこで,createQuery をまとめて1回で終わらせて,あとは小細工でフォローしてみたら,大分早くなった。(in のパラメータに List を使うのは増田先生の Twitter で教えてもらいました)
ちなみに,join fetch も試してみたが,cannot simultaneously fetch multiple bags という exception がでてできなかった。
失敗例
List
DocumentModel 120件超えのカルテで SelectAll で全選択する時間
3回続けて測定した結果
オリジナル方式 | まとめてクエリ方式 | |
---|---|---|
1回目 | 26.771秒 | 4.246秒 |
2回目 | 21.917秒 | 3.463秒 |
3回目 | 21.755秒 | 3.183秒 |
ejb/RemoteKarteServiceImpl.java
public ListgetDocuments(List ids) { List ret = new ArrayList (3); // まとめて query List mods = em.createQuery("from ModuleModel m where m.document.id in (:ids)") .setParameter("ids", ids).getResultList(); List imgs = em.createQuery("from SchemaModel m where m.document.id in (:ids)") .setParameter("ids", ids).getResultList(); // とってきた list を DocumentModel に分配 for (Long id : ids) { // DocuentBean を取得する DocumentModel document = em.find(DocumentModel.class, id); // ModuleBean を取得する List modules = new ArrayList (); for (ModuleModel m : mods) { if (m.getDocument().getId() == id) modules.add(m); } document.setModules(modules); // SchemaModel を取得する List images = new ArrayList (); for (SchemaModel m : imgs) { if (m.getDocument().getId() == id) images.add(m); } document.setSchema(images); ret.add(document); } return ret; }