From 28c9e757960811e126145fa8ee3b6e861c36b8da Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Wed, 18 Jan 2023 16:53:23 +0100 Subject: [PATCH] Otimized the DependantTable handling --- .../server/core/OrmQueryRequest.java | 64 +++++++++++++------ .../io/ebeaninternal/server/query/CQuery.java | 3 - .../server/query/CQueryEngine.java | 5 -- .../query/CQueryFetchSingleAttribute.java | 4 -- .../server/query/CQueryRowCount.java | 4 -- 5 files changed, 45 insertions(+), 35 deletions(-) diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/OrmQueryRequest.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/OrmQueryRequest.java index e312771fd1..73ed66028f 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/OrmQueryRequest.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/OrmQueryRequest.java @@ -40,11 +40,13 @@ public final class OrmQueryRequest extends BeanRequest implements SpiOrmQuery private PersistenceContext persistenceContext; private HashQuery cacheKey; private CQueryPlanKey queryPlanKey; + // The queryPlan during the request. + private CQueryPlan queryPlan; private SpiQuerySecondary secondaryQueries; private List cacheBeans; private BeanPropertyAssocMany manyProperty; private boolean inlineCountDistinct; - private Set dependentTables; + private boolean prepared; public OrmQueryRequest(SpiEbeanServer server, OrmQueryEngine queryEngine, SpiQuery query, SpiTransaction t) { super(server, t); @@ -68,6 +70,7 @@ public boolean isDeleteByStatement() { } else { // delete by ids due to cascading delete needs queryPlanKey = query.setDeleteByIdsPlan(); + queryPlan = null; return false; } } @@ -172,10 +175,24 @@ private void adapterPreQuery() { */ @Override public void prepareQuery() { - secondaryQueries = query.convertJoins(); - beanDescriptor.prepareQuery(query); - adapterPreQuery(); - queryPlanKey = query.prepare(this); + if (!prepared) { + secondaryQueries = query.convertJoins(); + beanDescriptor.prepareQuery(query); + adapterPreQuery(); + queryPlanKey = query.prepare(this); + prepared = true; + } + + } + + /** + * The queryPlanKey has to be updated, if elements are removed from an already prepared query. + */ + private void updateQueryPlanKey() { + if (prepared) { + queryPlanKey = query.prepare(this); + queryPlan = null; + } } public boolean isNativeSql() { @@ -470,7 +487,10 @@ public BeanPropertyAssocMany manyPropertyForOrderBy() { * query plan for this query exists. */ public CQueryPlan queryPlan() { - return beanDescriptor.queryPlan(queryPlanKey); + if (queryPlan == null) { + queryPlan = beanDescriptor.queryPlan(queryPlanKey); + } + return queryPlan; } /** @@ -488,6 +508,7 @@ public CQueryPlanKey queryPlanKey() { * Put the QueryPlan into the cache. */ public void putQueryPlan(CQueryPlan queryPlan) { + this.queryPlan = queryPlan; beanDescriptor.queryPlan(queryPlanKey, queryPlan); } @@ -497,7 +518,7 @@ public void resetBeanCacheAutoMode(boolean findOne) { } public boolean isQueryCachePut() { - return cacheKey != null && query.queryCacheMode().isPut(); + return cacheKey != null && queryPlan != null && query.queryCacheMode().isPut(); } public boolean isBeanCachePutMany() { @@ -606,7 +627,14 @@ public boolean getFromBeanCache() { BeanCacheResult cacheResult = beanDescriptor.cacheIdLookup(persistenceContext, idLookup.idValues()); // adjust the query (IN clause) based on the cache hits this.cacheBeans = idLookup.removeHits(cacheResult); - return idLookup.allHits(); + if (idLookup.allHits()) { + return true; + } else { + if (!this.cacheBeans.isEmpty()) { + updateQueryPlanKey(); + } + return false; + } } if (!beanDescriptor.isNaturalKeyCaching()) { return false; @@ -619,7 +647,14 @@ public boolean getFromBeanCache() { BeanCacheResult cacheResult = beanDescriptor.naturalKeyLookup(persistenceContext, naturalKeySet.keys()); // adjust the query (IN clause) based on the cache hits this.cacheBeans = data.removeHits(cacheResult); - return data.allHits(); + if (data.allHits()) { + return true; + } else { + if (!this.cacheBeans.isEmpty()) { + updateQueryPlanKey(); + } + return false; + } } } return false; @@ -688,7 +723,7 @@ private boolean readAuditQueryType() { } public void putToQueryCache(Object result) { - beanDescriptor.queryCachePut(cacheKey, new QueryCacheEntry(result, dependentTables, transaction.startNanoTime())); + beanDescriptor.queryCachePut(cacheKey, new QueryCacheEntry(result, queryPlan.dependentTables(), transaction.startNanoTime())); } /** @@ -758,15 +793,6 @@ public boolean isInlineCountDistinct() { return inlineCountDistinct; } - public void addDependentTables(Set tables) { - if (tables != null && !tables.isEmpty()) { - if (dependentTables == null) { - dependentTables = new LinkedHashSet<>(); - } - dependentTables.addAll(tables); - } - } - /** * Return true if no MaxRows or use LIMIT in SQL update. */ diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQuery.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQuery.java index 36d35c6599..da853e7efe 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQuery.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQuery.java @@ -754,7 +754,4 @@ public void handleLoadError(String fullName, Exception e) { query.handleLoadError(fullName, e); } - public Set dependentTables() { - return queryPlan.dependentTables(); - } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryEngine.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryEngine.java index 2d89e09681..9bc46a2aa6 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryEngine.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryEngine.java @@ -100,7 +100,6 @@ private > A findAttributeCollection(OrmQueryRequest r request.transaction().logSummary(rcQuery.summary()); } if (request.isQueryCachePut()) { - request.addDependentTables(rcQuery.dependentTables()); if (collection instanceof List) { collection = (A) Collections.unmodifiableList((List) collection); request.putToQueryCache(collection); @@ -167,7 +166,6 @@ public int findCount(OrmQueryRequest request) { request.transaction().end(); } if (request.isQueryCachePut()) { - request.addDependentTables(rcQuery.dependentTables()); request.putToQueryCache(count); } return count; @@ -355,9 +353,6 @@ BeanCollection findMany(OrmQueryRequest request) { cquery.auditFindMany(); } request.executeSecondaryQueries(false); - if (request.isQueryCachePut()) { - request.addDependentTables(cquery.dependentTables()); - } return beanCollection; } catch (SQLException e) { diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryFetchSingleAttribute.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryFetchSingleAttribute.java index a687beae5c..16d14d65a3 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryFetchSingleAttribute.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryFetchSingleAttribute.java @@ -168,10 +168,6 @@ public void profile() { .addQueryEvent(query.profileEventId(), profileOffset, desc.name(), rowCount, query.profileId()); } - Set dependentTables() { - return queryPlan.dependentTables(); - } - @Override public void cancel() { lock.lock(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryRowCount.java b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryRowCount.java index 4d43da157e..ca7073ea67 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryRowCount.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/query/CQueryRowCount.java @@ -140,10 +140,6 @@ public void profile() { .addQueryEvent(query.profileEventId(), profileOffset, desc.name(), rowCount, query.profileId()); } - Set dependentTables() { - return queryPlan.dependentTables(); - } - @Override public void cancel() { lock.lock();