Mit den folgenden CriteriaBuilder liefert Ergebnisse innerhalb von 1 Sekunde, wenn ich eine Karte von 1 oder 2 Einträge haben, aber wenn es 3 erreicht die Leistung der Abfrage fällt. Wenn dann ein vierter Eintrag hinzugefügt wird, wird die Leistung sogar noch mehr reduziert, bis zu dem Punkt, an dem ich sie nicht mehr gesehen habe.Warum sinkt die Abfrageleistung drastisch?
Ich habe versucht, stattdessen Sub-Abfragen zu verwenden, aber es scheint auf ein ähnliches Problem zu stoßen, wo 2 EXISTS-Unterabfragen Daten innerhalb einer angemessenen Zeit zurückgeben, aber 3 oder mehr werden zu einem großen Leistungseinbruch führen.
Ich habe festgestellt, dass ohne die ORDER BY die Abfrage funktioniert auch mit 3 Einträge (1 Sekunde oder weniger), aber sobald ich es wieder auf die gleichen 3 Einträge hinzufügen Suche dauert über 30 Sekunden. Hier
ist der Erbauer:
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);
Hier ist die SQL, die aus dem oben Builder erstellt wird, wenn ich 3 Map-Einträge:
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
Hier ist ein Beispiel der Tabellenstruktur:
Was ich aCH versuche IEVE ist eine Studie aus, in dem der Wert eines Feldes ‚james‘ enthält und der XML-Tag wäre ‚1‘ (1 Name, 2 Geschlecht). Der Grund, warum ich eine Karte verwende, ist, dass Sie vielleicht auch nach zusätzlichen Feldern suchen möchten, zum Beispiel nach Geschlecht. Ich denke, der einzige Weg, das zu funktionieren, wäre mit bestehenden Sub-Abfragen oder Joins, wie ich oben getan habe.
Leider ist diese Datenstruktur ziemlich schlecht, aber wurde aus einer früheren Datenbank-Design geerbt, so bin ich ein bisschen mit ihm stecken.
Hallo, hier ist ein toller Artikel über die Leistung der Abfrage zu kartieren, vielleicht wird es Ihnen helfen http://www.javaworld.com/article/2076240/build-ci-sdlc/optimize-a-query-on-a -map.html – Hrabosch
Das muss super langsam sein. Wenn Sie Ihre Tabellenstrukturen, Beispieldaten und die erwartete Ausgabe hinzufügen, können wir Ihnen helfen, eine gut funktionierende Abfrage zu finden. –