2222import java .util .function .Predicate ;
2323import java .util .regex .Pattern ;
2424
25+ import javax .annotation .Nullable ;
26+
2527import com .codahale .metrics .Counter ;
2628import com .codahale .metrics .Histogram ;
2729import com .codahale .metrics .Timer ;
@@ -199,13 +201,8 @@ public static class PerTable extends AbstractQueryMetrics
199201 public final Counter totalRowTombstonesFetched ;
200202 public final Counter totalQueriesCompleted ;
201203
202- public final Counter totalRowsToReturnEstimated ;
203- public final Counter totalRowsToFetchEstimated ;
204- public final Counter totalKeysToIterateEstimated ;
205- public final Counter totalCostEstimated ;
206-
207- public final Counter sortThenFilterQueriesCompleted ;
208- public final Counter filterThenSortQueriesCompleted ;
204+ @ Nullable
205+ public final QueryPlanMetrics queryPlanMetrics ;
209206
210207 /**
211208 * @param table the table to measure metrics for
@@ -225,13 +222,9 @@ public PerTable(TableMetadata table, QueryKind queryKind, Predicate<ReadCommand>
225222 totalRowTombstonesFetched = Metrics .counter (createMetricName ("TotalRowTombstonesFetched" ));
226223 totalQueriesCompleted = Metrics .counter (createMetricName ("TotalQueriesCompleted" ));
227224 totalQueryTimeouts = Metrics .counter (createMetricName ("TotalQueryTimeouts" ));
228- totalRowsToReturnEstimated = Metrics .counter (createMetricName ("TotalRowsToReturnEstimated" ));
229- totalRowsToFetchEstimated = Metrics .counter (createMetricName ("TotalRowsToFetchEstimated" ));
230- totalKeysToIterateEstimated = Metrics .counter (createMetricName ("TotalKeysToIterateEstimated" ));
231- totalCostEstimated = Metrics .counter (createMetricName ("TotalCostEstimated" ));
232-
233- sortThenFilterQueriesCompleted = Metrics .counter (createMetricName ("SortThenFilterQueriesCompleted" ));
234- filterThenSortQueriesCompleted = Metrics .counter (createMetricName ("FilterThenSortQueriesCompleted" ));
225+ queryPlanMetrics = (CassandraRelevantProperties .SAI_QUERY_PLAN_METRICS_ENABLED .getBoolean ())
226+ ? new QueryPlanMetrics ()
227+ : null ;
235228 }
236229
237230 @ Override
@@ -253,17 +246,40 @@ public void record(QueryContext.Snapshot snapshot)
253246 totalRowTombstonesFetched .inc (snapshot .rowTombstonesFetched );
254247
255248 QueryContext .PlanInfo queryPlanInfo = snapshot .queryPlanInfo ;
256- if (queryPlanInfo != null )
249+ if (queryPlanInfo != null && queryPlanMetrics != null )
257250 {
258- totalCostEstimated .inc (Math . round ( queryPlanInfo .costEstimated ) );
259- totalRowsToReturnEstimated .inc (Math . round ( queryPlanInfo .rowsToReturnEstimated ) );
260- totalRowsToFetchEstimated .inc (Math . round ( queryPlanInfo .rowsToFetchEstimated ) );
261- totalKeysToIterateEstimated .inc (Math . round ( queryPlanInfo .keysToIterateEstimated ) );
251+ queryPlanMetrics . totalCostEstimated .inc (queryPlanInfo .costEstimated );
252+ queryPlanMetrics . totalRowsToReturnEstimated .inc (queryPlanInfo .rowsToReturnEstimated );
253+ queryPlanMetrics . totalRowsToFetchEstimated .inc (queryPlanInfo .rowsToFetchEstimated );
254+ queryPlanMetrics . totalKeysToIterateEstimated .inc (queryPlanInfo .keysToIterateEstimated );
262255
263256 if (queryPlanInfo .filterExecutedAfterOrderedScan )
264- sortThenFilterQueriesCompleted .inc ();
257+ queryPlanMetrics . sortThenFilterQueriesCompleted .inc ();
265258 if (queryPlanInfo .searchExecutedBeforeOrder )
266- filterThenSortQueriesCompleted .inc ();
259+ queryPlanMetrics .filterThenSortQueriesCompleted .inc ();
260+ }
261+ }
262+
263+ public class QueryPlanMetrics
264+ {
265+ public final Counter totalRowsToReturnEstimated ;
266+ public final Counter totalRowsToFetchEstimated ;
267+ public final Counter totalKeysToIterateEstimated ;
268+ public final Counter totalCostEstimated ;
269+
270+ public final Counter sortThenFilterQueriesCompleted ;
271+ public final Counter filterThenSortQueriesCompleted ;
272+
273+
274+ public QueryPlanMetrics ()
275+ {
276+ totalRowsToReturnEstimated = Metrics .counter (createMetricName ("TotalRowsToReturnEstimated" ));
277+ totalRowsToFetchEstimated = Metrics .counter (createMetricName ("TotalRowsToFetchEstimated" ));
278+ totalKeysToIterateEstimated = Metrics .counter (createMetricName ("TotalKeysToIterateEstimated" ));
279+ totalCostEstimated = Metrics .counter (createMetricName ("TotalCostEstimated" ));
280+
281+ sortThenFilterQueriesCompleted = Metrics .counter (createMetricName ("SortThenFilterQueriesCompleted" ));
282+ filterThenSortQueriesCompleted = Metrics .counter (createMetricName ("FilterThenSortQueriesCompleted" ));
267283 }
268284 }
269285 }
@@ -311,33 +327,8 @@ public static class PerQuery extends AbstractQueryMetrics
311327 */
312328 public final Timer annGraphSearchLatency ;
313329
314- /** Query execution cost as estimated by the planner */
315- public final Histogram costEstimated ;
316-
317- /** Number of rows to be returned from the query as estimated by the planner */
318- public final Histogram rowsToReturnEstimated ;
319-
320- /** Number of rows to be fetched by the query as estimated by the planner */
321- public final Histogram rowsToFetchEstimated ;
322-
323- /** Number of rows to be fetched by the query as estimated by the planner */
324- public final Histogram keysToIterateEstimated ;
325-
326- /**
327- * Negative deceimal logarithm of selectivity of the query, before applying the LIMIT clause.
328- * We use logarithm because selectivity values can be very small (e.g. 10^-9).
329- */
330- public final Histogram logSelectivityEstimated ;
331-
332- /**
333- * Number of indexes referenced by the optimized query plan.
334- * The same index referenced from unrelated query clauses,
335- * leading to separate index searches, are counted separately.
336- */
337- public final Histogram indexReferencesInPlan ;
338-
339- /** Number of indexes referenced by the original query plan before optimization (as stated in the query text) */
340- public final Histogram indexReferencesInQuery ;
330+ @ Nullable
331+ public final QueryPlanMetrics queryPlanMetrics ;
341332
342333 /**
343334 * @param table the table to measure metrics for
@@ -370,13 +361,9 @@ public PerQuery(TableMetadata table, QueryKind queryKind, Predicate<ReadCommand>
370361 // Key vector metrics that translate to performance
371362 annGraphSearchLatency = Metrics .timer (createMetricName ("ANNGraphSearchLatency" ));
372363
373- costEstimated = Metrics .histogram (createMetricName ("CostEstimated" ), false );
374- rowsToReturnEstimated = Metrics .histogram (createMetricName ("RowsToReturnEstimated" ), true );
375- rowsToFetchEstimated = Metrics .histogram (createMetricName ("RowsToFetchEstimated" ), true );
376- keysToIterateEstimated = Metrics .histogram (createMetricName ("KeysToIterateEstimated" ), true );
377- logSelectivityEstimated = Metrics .histogram (createMetricName ("LogSelectivityEstimated" ), true );
378- indexReferencesInPlan = Metrics .histogram (createMetricName ("IndexReferencesInPlan" ), true );
379- indexReferencesInQuery = Metrics .histogram (createMetricName ("IndexReferencesInQuery" ), false );
364+ queryPlanMetrics = CassandraRelevantProperties .SAI_QUERY_PLAN_METRICS_ENABLED .getBoolean ()
365+ ? new QueryPlanMetrics ()
366+ : null ;
380367 }
381368
382369 @ Override
@@ -418,17 +405,73 @@ public void record(QueryContext.Snapshot snapshot)
418405 }
419406
420407 QueryContext .PlanInfo queryPlanInfo = snapshot .queryPlanInfo ;
421- if (queryPlanInfo != null )
408+ if (queryPlanInfo != null && queryPlanMetrics != null )
422409 {
423- costEstimated .update (Math .round (queryPlanInfo .costEstimated ));
424- rowsToReturnEstimated .update (Math .round (queryPlanInfo .rowsToReturnEstimated ));
425- rowsToFetchEstimated .update (Math .round (queryPlanInfo .rowsToFetchEstimated ));
426- keysToIterateEstimated .update (Math .round (queryPlanInfo .keysToIterateEstimated ));
427- double logSelectivity = -Math .log10 (queryPlanInfo .selectivityEstimated );
428- logSelectivityEstimated .update ((int ) (Math .min (20 , Math .floor (logSelectivity ))));
429- indexReferencesInQuery .update (queryPlanInfo .indexReferencesInQuery );
430- indexReferencesInPlan .update (queryPlanInfo .indexReferencesInPlan );
410+ queryPlanMetrics .costEstimated .update (queryPlanInfo .costEstimated );
411+ queryPlanMetrics .rowsToReturnEstimated .update (queryPlanInfo .rowsToReturnEstimated );
412+ queryPlanMetrics .rowsToFetchEstimated .update (queryPlanInfo .rowsToFetchEstimated );
413+ queryPlanMetrics .keysToIterateEstimated .update (queryPlanInfo .keysToIterateEstimated );
414+ queryPlanMetrics .logSelectivityEstimated .update (queryPlanInfo .logSelectivityEstimated );
415+ queryPlanMetrics .indexReferencesInQuery .update (queryPlanInfo .indexReferencesInQuery );
416+ queryPlanMetrics .indexReferencesInPlan .update (queryPlanInfo .indexReferencesInPlan );
431417 }
432418 }
419+
420+ /// Metrics related to query planning.
421+ /// Moved to separate class so they can be enabled/disabled as a group.
422+ public class QueryPlanMetrics
423+ {
424+ /**
425+ * Query execution cost as estimated by the planner
426+ */
427+ public final Histogram costEstimated ;
428+
429+ /**
430+ * Number of rows to be returned from the query as estimated by the planner
431+ */
432+ public final Histogram rowsToReturnEstimated ;
433+
434+ /**
435+ * Number of rows to be fetched by the query as estimated by the planner
436+ */
437+ public final Histogram rowsToFetchEstimated ;
438+
439+ /**
440+ * Number of keys to be iterated by the query as estimated by the planner
441+ */
442+ public final Histogram keysToIterateEstimated ;
443+
444+ /**
445+ * Negative decimal logarithm of selectivity of the query, before applying the LIMIT clause.
446+ * We use logarithm because selectivity values can be very small (e.g. 10^-9).
447+ */
448+ public final Histogram logSelectivityEstimated ;
449+
450+ /**
451+ * Number of indexes referenced by the optimized query plan.
452+ * The same index referenced from unrelated query clauses,
453+ * leading to separate index searches, are counted separately.
454+ */
455+ public final Histogram indexReferencesInPlan ;
456+
457+ /**
458+ * Number of indexes referenced by the original query plan before optimization (as stated in the query text)
459+ */
460+ public final Histogram indexReferencesInQuery ;
461+
462+ QueryPlanMetrics ()
463+ {
464+ costEstimated = Metrics .histogram (createMetricName ("CostEstimated" ), false );
465+ rowsToReturnEstimated = Metrics .histogram (createMetricName ("RowsToReturnEstimated" ), true );
466+ rowsToFetchEstimated = Metrics .histogram (createMetricName ("RowsToFetchEstimated" ), true );
467+ keysToIterateEstimated = Metrics .histogram (createMetricName ("KeysToIterateEstimated" ), true );
468+ logSelectivityEstimated = Metrics .histogram (createMetricName ("LogSelectivityEstimated" ), true );
469+ indexReferencesInPlan = Metrics .histogram (createMetricName ("IndexReferencesInPlan" ), true );
470+ indexReferencesInQuery = Metrics .histogram (createMetricName ("IndexReferencesInQuery" ), false );
471+ }
472+ }
473+
433474 }
475+
476+
434477}
0 commit comments