Refactor for query plan capture with initial threshold micros

This commit is contained in:
rob bygrave
2019-12-23 10:28:08 +13:00
parent 71295077a5
commit 6fcac27dfe
25 changed files with 388 additions and 114 deletions
@@ -0,0 +1,46 @@
package io.ebeaninternal.api;
import io.ebean.meta.MetricType;
import io.ebean.meta.MetricVisitor;
import io.ebean.metric.MetricFactory;
import io.ebean.metric.TimedMetric;
/**
* Extra metrics collected to measure internal behaviour.
*/
public class ExtraMetrics {
private final TimedMetric bindCapture;
private final TimedMetric planCollect;
/**
* Create the extra metrics.
*/
public ExtraMetrics() {
final MetricFactory factory = MetricFactory.get();
this.bindCapture = factory.createTimedMetric(MetricType.ORM, "ebean.queryplan.bindcapture");
this.planCollect = factory.createTimedMetric(MetricType.ORM, "ebean.queryplan.collect");
}
/**
* Timed metric for bind capture used with query plan collection.
*/
public TimedMetric getBindCapture() {
return bindCapture;
}
/**
* Timed metric for query plan collection.
*/
public TimedMetric getPlanCollect() {
return planCollect;
}
/**
* Collect the metrics.
*/
public void visitMetrics(MetricVisitor visitor) {
bindCapture.visit(visitor);
planCollect.visit(visitor);
}
}
@@ -0,0 +1,22 @@
package io.ebeaninternal.api;
import io.ebean.meta.QueryPlanRequest;
import io.ebeaninternal.server.type.bindcapture.BindCapture;
class NoopQueryBindCapture implements SpiQueryBindCapture {
@Override
public boolean collectFor(long timeMicros) {
return false;
}
@Override
public void setBind(BindCapture bindCapture, long timeMicros, long startNanos) {
// do nothing
}
@Override
public void collectQueryPlan(QueryPlanRequest request) {
// do nothing
}
}
@@ -0,0 +1,9 @@
package io.ebeaninternal.api;
class NoopQueryPlanManager implements QueryPlanManager {
@Override
public SpiQueryBindCapture createBindCapture(SpiQueryPlan queryPlan) {
return SpiQueryBindCapture.NOOP;
}
}
@@ -0,0 +1,14 @@
package io.ebeaninternal.api;
/**
* Manage query plan capture.
*/
public interface QueryPlanManager {
QueryPlanManager NOOP = new NoopQueryPlanManager();
/**
* Create the bind capture for the given query plan.
*/
SpiQueryBindCapture createBindCapture(SpiQueryPlan queryPlan);
}
@@ -12,7 +12,6 @@ import io.ebean.TxScope;
import io.ebean.bean.BeanCollectionLoader;
import io.ebean.bean.BeanLoader;
import io.ebean.bean.CallOrigin;
import io.ebean.bean.ObjectGraphNode;
import io.ebean.config.ServerConfig;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.event.readaudit.ReadAuditLogger;
@@ -311,4 +310,9 @@ public interface SpiEbeanServer extends ExtendedServer, EbeanServer, BeanLoader,
* Execute the sql update regardless of transaction batch mode.
*/
int executeNow(SpiSqlUpdate sqlUpdate);
/**
* Create a query bind capture for the given query plan.
*/
SpiQueryBindCapture createQueryBindCapture(SpiQueryPlan queryPlan);
}
@@ -0,0 +1,31 @@
package io.ebeaninternal.api;
import io.ebean.meta.QueryPlanRequest;
import io.ebeaninternal.server.type.bindcapture.BindCapture;
/**
* Capture query bind values and with those actual database query plans.
*/
public interface SpiQueryBindCapture {
/**
* NOOP implementation.
*/
SpiQueryBindCapture NOOP = new NoopQueryBindCapture();
/**
* Return true if the query just executed should be bind captured to collect
* the query plan from (as the query time is large / interesting).
*/
boolean collectFor(long timeMicros);
/**
* Set the bind capture and the related query execution time.
*/
void setBind(BindCapture bindCapture, long timeMicros, long startNanos);
/**
* Collect the query execution plan usually executing the query to do so.
*/
void collectQueryPlan(QueryPlanRequest request);
}
@@ -0,0 +1,34 @@
package io.ebeaninternal.api;
import io.ebean.ProfileLocation;
/**
* The internal ORM "query plan".
*/
public interface SpiQueryPlan {
/**
* The related entity bean type
*/
Class<?> getBeanType();
/**
* The plan name.
*/
String getName();
/**
* The hash for the query plan.
*/
String getHash();
/**
* The SQL for the query plan.
*/
String getSql();
/**
* The related profile location.
*/
ProfileLocation getProfileLocation();
}