diff --git a/pkg/sql/conn_executor.go b/pkg/sql/conn_executor.go index 768c91e7b608..213419be357f 100644 --- a/pkg/sql/conn_executor.go +++ b/pkg/sql/conn_executor.go @@ -268,7 +268,9 @@ func NewServer(cfg *ExecutorConfig, pool *mon.BytesMonitor) *Server { return &Server{ cfg: cfg, EngineMetrics: EngineMetrics{ - DistSQLSelectCount: metric.NewCounter(MetaDistSQLSelect), + DistSQLSelectCount: metric.NewCounter(MetaDistSQLSelect), + SQLOptCount: metric.NewCounter(MetaSQLOpt), + SQLOptFallbackCount: metric.NewCounter(MetaSQLOptFallback), // TODO(mrtracy): See HistogramWindowInterval in server/config.go for the 6x factor. DistSQLExecLatency: metric.NewLatency(MetaDistSQLExecLatency, 6*metricsSampleInterval), diff --git a/pkg/sql/conn_executor_exec.go b/pkg/sql/conn_executor_exec.go index 78bed963d097..34222f570c5f 100644 --- a/pkg/sql/conn_executor_exec.go +++ b/pkg/sql/conn_executor_exec.go @@ -656,7 +656,7 @@ func (ex *connExecutor) execStmtInParallel( planner.statsCollector.PhaseTimes()[plannerEndExecStmt] = timeutil.Now() ex.recordStatementSummary( - planner, stmt, false /* distSQLUsed*/, ex.extraTxnState.autoRetryCounter, + planner, stmt, false /* distSQLUsed*/, false /* optUsed */, ex.extraTxnState.autoRetryCounter, res.RowsAffected(), err, &ex.server.EngineMetrics, ) if ex.server.cfg.TestingKnobs.AfterExecute != nil { @@ -807,8 +807,9 @@ func (ex *connExecutor) dispatchToExecutionEngine( return err } ex.recordStatementSummary( - planner, stmt, useDistSQL, ex.extraTxnState.autoRetryCounter, - res.RowsAffected(), res.Err(), &ex.server.EngineMetrics, + planner, stmt, useDistSQL, optimizerPlanned, + ex.extraTxnState.autoRetryCounter, res.RowsAffected(), res.Err(), + &ex.server.EngineMetrics, ) if ex.server.cfg.TestingKnobs.AfterExecute != nil { ex.server.cfg.TestingKnobs.AfterExecute(ctx, stmt.String(), res.Err()) diff --git a/pkg/sql/exec_util.go b/pkg/sql/exec_util.go index 6e51e67ac406..1f9ed8dfda71 100644 --- a/pkg/sql/exec_util.go +++ b/pkg/sql/exec_util.go @@ -176,6 +176,18 @@ var ( Measurement: "Latency", Unit: metric.Unit_NANOSECONDS, } + MetaSQLOpt = metric.Metadata{ + Name: "sql.optimizer.count", + Help: "Number of statements which ran with the cost-based optimizer", + Measurement: "SQL Statements", + Unit: metric.Unit_COUNT, + } + MetaSQLOptFallback = metric.Metadata{ + Name: "sql.optimizer.fallback.count", + Help: "Number of statements which the cost-based optimizer was unable to plan", + Measurement: "SQL Statements", + Unit: metric.Unit_COUNT, + } MetaDistSQLSelect = metric.Metadata{ Name: "sql.distsql.select.count", Help: "Number of DistSQL SELECT statements", diff --git a/pkg/sql/executor_statement_metrics.go b/pkg/sql/executor_statement_metrics.go index 3f7e5fad7754..9221f40ef618 100644 --- a/pkg/sql/executor_statement_metrics.go +++ b/pkg/sql/executor_statement_metrics.go @@ -18,6 +18,7 @@ import ( "time" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" + "github.com/cockroachdb/cockroach/pkg/sql/sessiondata" "github.com/cockroachdb/cockroach/pkg/util/log" "github.com/cockroachdb/cockroach/pkg/util/metric" ) @@ -64,7 +65,12 @@ type phaseTimes [sessionNumPhases]time.Time // EngineMetrics groups a set of SQL metrics. type EngineMetrics struct { // The subset of SELECTs that are processed through DistSQL. - DistSQLSelectCount *metric.Counter + DistSQLSelectCount *metric.Counter + // The subset of queries that are processed by the cost-based optimizer. + SQLOptCount *metric.Counter + // The subset of queries which we attempted and failed to plan with the + // cost-based optimizer. + SQLOptFallbackCount *metric.Counter DistSQLExecLatency *metric.Histogram SQLExecLatency *metric.Histogram DistSQLServiceLatency *metric.Histogram @@ -89,6 +95,7 @@ func (ex *connExecutor) recordStatementSummary( planner *planner, stmt Statement, distSQLUsed bool, + optUsed bool, automaticRetryCount int, rowsAffected int, err error, @@ -122,6 +129,14 @@ func (ex *connExecutor) recordStatementSummary( execOverhead := svcLat - processingLat if automaticRetryCount == 0 { + if optUsed { + m.SQLOptCount.Inc(1) + } + + if !optUsed && planner.SessionData().OptimizerMode == sessiondata.OptimizerOn { + m.SQLOptFallbackCount.Inc(1) + } + if distSQLUsed { if _, ok := stmt.AST.(*tree.Select); ok { m.DistSQLSelectCount.Inc(1) diff --git a/pkg/sql/metric_test.go b/pkg/sql/metric_test.go index 0ca31b6dd212..d2240b6aee31 100644 --- a/pkg/sql/metric_test.go +++ b/pkg/sql/metric_test.go @@ -34,6 +34,8 @@ type queryCounter struct { txnBeginCount int64 selectCount int64 distSQLSelectCount int64 + optCount int64 + fallbackCount int64 updateCount int64 insertCount int64 deleteCount int64 @@ -54,6 +56,7 @@ func TestQueryCounts(t *testing.T) { var testcases = []queryCounter{ // The counts are deltas for each query. + {query: "SET EXPERIMENTAL_OPT = 'off'", miscCount: 1}, {query: "SET DISTSQL = 'off'", miscCount: 1}, {query: "BEGIN; END", txnBeginCount: 1, txnCommitCount: 1}, {query: "SELECT 1", selectCount: 1, txnCommitCount: 1}, @@ -81,6 +84,11 @@ func TestQueryCounts(t *testing.T) { {query: "SET DISTSQL = 'off'", miscCount: 1}, {query: "DROP TABLE mt.n", ddlCount: 1}, {query: "SET database = system", miscCount: 1}, + {query: "SET EXPERIMENTAL_OPT = 'on'", miscCount: 1, fallbackCount: 1}, + {query: "SELECT 3", selectCount: 1, optCount: 1}, + {query: "CREATE TABLE mt.n (num INTEGER PRIMARY KEY)", ddlCount: 1, fallbackCount: 1}, + {query: "UPDATE mt.n SET num = num + 1", updateCount: 1, fallbackCount: 1}, + {query: "SET EXPERIMENTAL_OPT = 'off'", miscCount: 1}, } accum := initializeQueryCounter(s) @@ -130,6 +138,12 @@ func TestQueryCounts(t *testing.T) { if accum.failureCount, err = checkCounterDelta(s, sql.MetaFailure, accum.failureCount, tc.failureCount); err != nil { t.Errorf("%q: %s", tc.query, err) } + if accum.optCount, err = checkCounterDelta(s, sql.MetaSQLOpt, accum.optCount, tc.optCount); err != nil { + t.Errorf("%q: %s", tc.query, err) + } + if accum.fallbackCount, err = checkCounterDelta(s, sql.MetaSQLOptFallback, accum.fallbackCount, tc.fallbackCount); err != nil { + t.Errorf("%q: %s", tc.query, err) + } }) } } diff --git a/pkg/sql/metric_util_test.go b/pkg/sql/metric_util_test.go index 4541af7920ed..f60fa746e145 100644 --- a/pkg/sql/metric_util_test.go +++ b/pkg/sql/metric_util_test.go @@ -29,6 +29,7 @@ func initializeQueryCounter(s serverutils.TestServerInterface) queryCounter { return queryCounter{ txnBeginCount: s.MustGetSQLCounter(sql.MetaTxnBegin.Name), selectCount: s.MustGetSQLCounter(sql.MetaSelect.Name), + optCount: s.MustGetSQLCounter(sql.MetaSQLOpt.Name), distSQLSelectCount: s.MustGetSQLCounter(sql.MetaDistSQLSelect.Name), updateCount: s.MustGetSQLCounter(sql.MetaUpdate.Name), insertCount: s.MustGetSQLCounter(sql.MetaInsert.Name),