Skip to content

Commit f29684e

Browse files
andy-kimballyuzefovich
authored andcommitted
sql: add rows_read metric
Add new `sql.statements.rows_read.count` metric that counts the number of index rows read by SQL statements. This is the same value that's collected by SQL stats for each statement and transaction, except in aggregated metric form. Epic: none Release note (sql change): Added sql.statements.rows_read.count metric that counts the number of index rows read by SQL statements.
1 parent 1a4ff79 commit f29684e

File tree

7 files changed

+98
-0
lines changed

7 files changed

+98
-0
lines changed

docs/generated/metrics/metrics.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8747,6 +8747,22 @@ layers:
87478747
unit: COUNT
87488748
aggregation: AVG
87498749
derivative: NON_NEGATIVE_DERIVATIVE
8750+
- name: sql.statements.rows_read.count
8751+
exported_name: sql_statements_rows_read_count
8752+
description: Number of rows read by SQL statements from primary and secondary indexes
8753+
y_axis_label: SQL Statements
8754+
type: COUNTER
8755+
unit: COUNT
8756+
aggregation: AVG
8757+
derivative: NON_NEGATIVE_DERIVATIVE
8758+
- name: sql.statements.rows_read.count.internal
8759+
exported_name: sql_statements_rows_read_count_internal
8760+
description: Number of rows read by SQL statements from primary and secondary indexes (internal queries)
8761+
y_axis_label: SQL Internal Statements
8762+
type: COUNTER
8763+
unit: COUNT
8764+
aggregation: AVG
8765+
derivative: NON_NEGATIVE_DERIVATIVE
87508766
- name: sql.stats.activity.update.latency
87518767
exported_name: sql_stats_activity_update_latency
87528768
description: The latency of updates made by the SQL activity updater job. Includes failed update attempts

pkg/roachprod/agents/opentelemetry/cockroachdb_metrics.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2169,6 +2169,8 @@ var cockroachdbMetrics = map[string]string{
21692169
"sql_statements_active_internal": "sql.statements.active.internal",
21702170
"sql_statements_auto_retry_count": "sql.statements.auto_retry.count",
21712171
"sql_statements_auto_retry_count_internal": "sql.statements.auto_retry.count.internal",
2172+
"sql_statements_rows_read_count": "sql.statements.rows_read.count",
2173+
"sql_statements_rows_read_count_internal": "sql.statements.rows_read.count.internal",
21722174
"sql_stats_activity_update_latency": "sql.stats.activity.update.latency",
21732175
"sql_stats_activity_update_latency_bucket": "sql.stats.activity.update.latency.bucket",
21742176
"sql_stats_activity_update_latency_count": "sql.stats.activity.update.latency.count",

pkg/sql/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,6 +972,7 @@ go_test(
972972
"//pkg/util/log/logconfig",
973973
"//pkg/util/log/logpb",
974974
"//pkg/util/log/logtestutils",
975+
"//pkg/util/metamorphic",
975976
"//pkg/util/metric",
976977
"//pkg/util/mon",
977978
"//pkg/util/protoutil",

pkg/sql/conn_executor.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,7 @@ func makeMetrics(internal bool, sv *settings.Values) Metrics {
625625
FullTableOrIndexScanRejectedCount: metric.NewCounter(getMetricMeta(MetaFullTableOrIndexScanRejected, internal)),
626626
TxnRetryCount: metric.NewCounter(getMetricMeta(MetaTxnRetry, internal)),
627627
StatementRetryCount: metric.NewCounter(getMetricMeta(MetaStatementRetry, internal)),
628+
StatementRowsRead: metric.NewCounter(getMetricMeta(MetaStatementRowsRead, internal)),
628629
},
629630
StartedStatementCounters: makeStartedStatementCounters(internal),
630631
ExecutedStatementCounters: makeExecutedStatementCounters(internal),

pkg/sql/exec_util.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,6 +1514,12 @@ var (
15141514
Measurement: "SQL Statements",
15151515
Unit: metric.Unit_COUNT,
15161516
}
1517+
MetaStatementRowsRead = metric.Metadata{
1518+
Name: "sql.statements.rows_read.count",
1519+
Help: "Number of rows read by SQL statements from primary and secondary indexes",
1520+
Measurement: "SQL Statements",
1521+
Unit: metric.Unit_COUNT,
1522+
}
15171523
)
15181524

15191525
func getMetricMeta(meta metric.Metadata, internal bool) metric.Metadata {

pkg/sql/executor_statement_metrics.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ type EngineMetrics struct {
8383
// StatementRetryCount counts the number of automatic statement retries that
8484
// have occurred under READ COMMITTED isolation.
8585
StatementRetryCount *metric.Counter
86+
87+
// StatementRowsRead counts the number of rows read by SQL statements from
88+
// primary and secondary indexes. Note that some secondary indexes can have
89+
// multiple index rows per primary index row (e.g. inverted and vector).
90+
StatementRowsRead *metric.Counter
8691
}
8792

8893
// EngineMetrics implements the metric.Struct interface.
@@ -196,6 +201,10 @@ func (ex *connExecutor) recordStatementSummary(
196201
if automaticRetryStmtCount > 0 {
197202
autoRetryReason = planner.autoRetryStmtReason
198203
}
204+
205+
// Update SQL statement metrics.
206+
ex.metrics.EngineMetrics.StatementRowsRead.Inc(stats.rowsRead)
207+
199208
if ex.statsCollector.EnabledForTransaction() {
200209
recordedStmtStats := &sqlstats.RecordedStmtStats{
201210
FingerprintID: stmtFingerprintID,

pkg/sql/metric_test.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package sql_test
88
import (
99
"bytes"
1010
"context"
11+
"fmt"
1112
"regexp"
1213
"testing"
1314

@@ -18,8 +19,10 @@ import (
1819
"github.com/cockroachdb/cockroach/pkg/sql/catalog/lease"
1920
"github.com/cockroachdb/cockroach/pkg/testutils"
2021
"github.com/cockroachdb/cockroach/pkg/testutils/serverutils"
22+
"github.com/cockroachdb/cockroach/pkg/testutils/sqlutils"
2123
"github.com/cockroachdb/cockroach/pkg/util/leaktest"
2224
"github.com/cockroachdb/cockroach/pkg/util/log"
25+
"github.com/cockroachdb/cockroach/pkg/util/metamorphic"
2326
"github.com/cockroachdb/cockroach/pkg/util/metric"
2427
"github.com/stretchr/testify/require"
2528
)
@@ -205,6 +208,66 @@ func TestQueryCounts(t *testing.T) {
205208
}
206209
}
207210

211+
func TestStatementMetrics(t *testing.T) {
212+
defer leaktest.AfterTest(t)()
213+
defer log.Scope(t).Close(t)
214+
215+
params, _ := createTestServerParamsAllowTenants()
216+
srv, sqlDB, _ := serverutils.StartServer(t, params)
217+
defer srv.Stopper().Stop(context.Background())
218+
runner := sqlutils.MakeSQLRunner(sqlDB)
219+
s := srv.ApplicationLayer()
220+
221+
runner.Exec(t, `CREATE DATABASE db`)
222+
runner.Exec(t, `CREATE TABLE db.t (x INT PRIMARY KEY, y INT, a STRING[], v VECTOR(2))`)
223+
runner.Exec(t, `CREATE INDEX ON db.t (y)`)
224+
runner.Exec(t, `CREATE INVERTED INDEX ON db.t (a)`)
225+
runner.Exec(t, `CREATE VECTOR INDEX ON db.t (v)`)
226+
runner.Exec(t, `INSERT INTO db.t VALUES (1, 10, ARRAY['apple', 'orange'], '[1, 2]')`)
227+
runner.Exec(t, `INSERT INTO db.t VALUES (2, 20, ARRAY['banana'], '[3, 4]')`)
228+
runner.Exec(t, `INSERT INTO db.t VALUES (3, 30, ARRAY['apple', 'pear', 'mango'], '[5, 6]')`)
229+
230+
testCases := []struct {
231+
query string
232+
rowsRead int64
233+
// If true, then skip metamorphic testing for this query.
234+
skipMetamorphic bool
235+
}{
236+
{query: `SELECT * FROM db.t WHERE x = 1`, rowsRead: 1},
237+
{query: `SELECT * FROM db.t WHERE x <= 2`, rowsRead: 2},
238+
{query: `SELECT * FROM db.t WHERE a @> ARRAY['apple']`, rowsRead: 4},
239+
{
240+
query: `SELECT * FROM db.t@t_a_idx t1, db.t t2 WHERE t1.a @> t2.a`,
241+
rowsRead: 12,
242+
// Skip this variation under metamorphic testing because the inverted
243+
// joiner batch size can affect number of rows read.
244+
skipMetamorphic: true,
245+
},
246+
{query: `SELECT * FROM db.t ORDER BY v <-> '[2, 2]' LIMIT 1`, rowsRead: 3},
247+
}
248+
249+
lastRowsRead := s.MustGetSQLCounter(sql.MetaStatementRowsRead.Name)
250+
251+
for _, tc := range testCases {
252+
t.Run(tc.query, func(t *testing.T) {
253+
for _, vectorized := range []string{"off", "on"} {
254+
runner.Exec(t, "SET vectorize = $1", vectorized)
255+
t.Run(fmt.Sprintf("vectorize = %s", vectorized), func(t *testing.T) {
256+
if tc.skipMetamorphic && metamorphic.IsMetamorphicBuild() {
257+
return
258+
}
259+
260+
runner.Exec(t, tc.query)
261+
actual, err := checkCounterDelta(
262+
s, sql.MetaStatementRowsRead, lastRowsRead, tc.rowsRead)
263+
require.NoError(t, err)
264+
lastRowsRead = actual
265+
})
266+
}
267+
})
268+
}
269+
}
270+
208271
func TestAbortCountConflictingWrites(t *testing.T) {
209272
defer leaktest.AfterTest(t)()
210273
defer log.Scope(t).Close(t)

0 commit comments

Comments
 (0)