次のCriteriaBuilderを使用すると、1または2のエントリのマップがあるときに1秒以内に結果が返されますが、3に達するとクエリのパフォーマンスが低下します。その後、4番目のエントリを追加すると、結果セットを返すのを実際に見たことのないポイントにパフォーマンスがさらに低下します。クエリのパフォーマンスが大幅に低下するのはなぜですか?
代わりにサブクエリを使用しようとしましたが、2 EXISTSサブクエリが妥当な時間内にデータを返しますが、3つ以上の場合はパフォーマンスが大幅に低下するという同様の問題が発生しているようです。
ORDER BYを指定しないと、3つのエントリ(1秒以下)でもクエリがうまく動作することに気付きましたが、同じ3つのエントリに追加するとすぐに30秒以上かかることになります。ここで
はビルダーです:
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Study> q = builder.createQuery(Study.class);
Root<Study> rootStudy = q.from(Study.class);
List<Predicate> pList = new ArrayList<Predicate>(searchMap.size());
q.select(rootStudy);
Join<Study, Demographics> dem = rootStudy.join("demographics");
Join<Study, MetaData> met = rootStudy.join("metadata");
// add all conditions
for (Map.Entry<XmlTagHashKey, String> entry : searchMap.entrySet()) {
MapJoin< Demographics, XmlTagHashKey, Field2 > mapJoin = demJoin.joinMap("fields");
Path<String> attributePath = mapJoin.get("value");
Predicate p = builder.and(builder.equal(mapJoin.key(), entry.getKey()),
builder.like(attributePath, "%" + entry.getValue() + "%"));
pList.add(p);
}
q.where(pList.toArray(new Predicate[]{}));
q.orderBy(builder.desc( met.<String>get(XMLTagEnum.bbrad_status_updated.name())));
TypedQuery<Study> typedQuery = em.createQuery(q);
typedQuery.setMaxResults(100);
return getResultsList(typedQuery);
ここで私は3つのマップエントリ持っている時には、上記ビルダーから作成されたSQLされます。ここでは
SELECT t1.id,
t1.study_id,
t1.demographics_id,
t1.metadata_id
FROM demographics_has_fields t8,
field t7,
demographics_has_fields t6,
field t5,
demographics_has_fields t4,
field t3,
demographics t2,
study t1,
metadata t0
WHERE (((((t6.xmltag = ?)
AND t5.value LIKE ?)
AND ((t4.xmltag = ?)
AND t3.value LIKE ?))
AND ((t8.xmltag = ?)
AND t7.value LIKE ?))
AND (((((t2.id = t1.demographics_id)
AND ((t6.demographics_id = t2.id)
AND (t5.id = t6.field_id)))
AND ((t4.demographics_id = t2.id)
AND (t3.id = t4.field_id)))
AND ((t8.demographics_id = t2.id)
AND (t7.id = t8.field_id)))
AND (t0.id = t1.metadata_id)))
ORDER BY t0.bbradstatusupdated DESC
は、テーブル構造の例を示します。私はACHしようとしています何
ieveは、フィールドの値に 'james'が含まれ、xmlタグが '1'(1は名前、2は性別)のStudyを選択することです。私が地図を使用するのは、ジェンダーのような追加のフィールドを検索したいからです。私はこれが動作する唯一の方法は、上記のようにサブクエリまたはジョインが存在することだと思います。
残念ながら、このデータ構造はかなり悪いですが、以前のデータベース設計から継承されたので、私はそれに固執しています。
こんにちは、ここでは、マップするクエリのパフォーマンスについての素晴らしい記事です。多分それはあなたを助けるでしょうhttp://www.javaworld.com/article/2076240/build-ci-sdlc/optimize-a-query-on-a -map.html – Hrabosch
これは超低速でなければなりません。テーブル構造、サンプルデータ、期待される出力を追加すると、うまくいくクエリを見つけるのに役立つかもしれません –