Skip to content

Commit

Permalink
Merge pull request #79240 from xinhaoz/backport21.2-78333
Browse files Browse the repository at this point in the history
release 21.2: sql: record index usage stats in index joins
  • Loading branch information
xinhaoz authored Apr 1, 2022
2 parents bc0813f + a19efd2 commit d608a0e
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 7 deletions.
6 changes: 4 additions & 2 deletions pkg/ccl/serverccl/statusccl/tenant_status_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,7 @@ VALUES (1, 10, 100), (2, 20, 200), (3, 30, 300)
Exec(t, "SELECT * FROM test")

// Record scan on secondary index.
// Note that this is an index join and will also read from the primary index.
cluster.tenantConn(randomServer).
Exec(t, "SELECT * FROM test@test_a_idx")
testTableIDStr := cluster.tenantConn(randomServer).
Expand All @@ -436,7 +437,7 @@ WHERE
table_id = ` + testTableIDStr
// Assert index usage data was inserted.
expected := [][]string{
{testTableIDStr, "1", "1", "true"},
{testTableIDStr, "1", "2", "true"}, // Primary index
{testTableIDStr, "2", "1", "true"},
}
cluster.tenantConn(randomServer).CheckQueryResults(t, query, expected)
Expand Down Expand Up @@ -617,6 +618,7 @@ VALUES (1, 10, 100), (2, 20, 200), (3, 30, 300)
testingCluster.tenantConn(0).Exec(t, "SELECT * FROM idx_test.test")

// Record scan on secondary index.
// Note that this is an index join and will also read from the primary index.
testingCluster.tenantConn(1).Exec(t, "SELECT * FROM idx_test.test@test_a_idx")
testTableIDStr := testingCluster.tenantConn(2).QueryStr(t, "SELECT 'idx_test.test'::regclass::oid")[0][0]
testTableID, err := strconv.Atoi(testTableIDStr)
Expand All @@ -635,7 +637,7 @@ WHERE
`
actual := testingCluster.tenantConn(2).QueryStr(t, query, testTableID)
expected := [][]string{
{testTableIDStr, "1", "1", "true"},
{testTableIDStr, "1", "2", "true"},
{testTableIDStr, "2", "1", "true"},
}

Expand Down
29 changes: 25 additions & 4 deletions pkg/server/index_usage_stats_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ func TestStatusAPIIndexUsage(t *testing.T) {
LastRead: timeutil.Now(),
}

expectedStatsIndexPrimary := roachpb.IndexUsageStatistics{
TotalReadCount: 1,
LastRead: timeutil.Now(),
}

firstPgURL, firstServerConnCleanup := sqlutils.PGUrl(
t, firstServer.ServingSQLAddr(), "CreateConnections" /* prefix */, url.User(security.RootUser))
defer firstServerConnCleanup()
Expand Down Expand Up @@ -110,6 +115,11 @@ func TestStatusAPIIndexUsage(t *testing.T) {
require.NoError(t, err)
require.False(t, rows.Next())

indexKeyPrimary := roachpb.IndexUsageKey{
TableID: roachpb.TableID(tableID),
IndexID: 1, // t@t_pkey
}

indexKeyA := roachpb.IndexUsageKey{
TableID: roachpb.TableID(tableID),
IndexID: 2, // t@t_a_idx
Expand Down Expand Up @@ -149,7 +159,7 @@ func TestStatusAPIIndexUsage(t *testing.T) {
_, err = secondServerSQLConn.Exec("SELECT k FROM t WHERE a = 10 AND b = 200")
require.NoError(t, err)

// Record a full scan over t_b_idx.
// Record an index join and full scan of t_b_idx.
_, err = secondServerSQLConn.Exec("SELECT * FROM t@t_b_idx")
require.NoError(t, err)

Expand All @@ -163,20 +173,29 @@ func TestStatusAPIIndexUsage(t *testing.T) {
thirdLocalStatsReader := thirdServer.SQLServer().(*sql.Server).GetLocalIndexStatistics()

// First node should have nothing.
stats := firstLocalStatsReader.Get(indexKeyA.TableID, indexKeyA.IndexID)
stats := firstLocalStatsReader.Get(indexKeyPrimary.TableID, indexKeyPrimary.IndexID)
require.Equal(t, roachpb.IndexUsageStatistics{}, stats, "expecting empty stats on node 1, but found %v", stats)

stats = firstLocalStatsReader.Get(indexKeyA.TableID, indexKeyA.IndexID)
require.Equal(t, roachpb.IndexUsageStatistics{}, stats, "expecting empty stats on node 1, but found %v", stats)

stats = firstLocalStatsReader.Get(indexKeyB.TableID, indexKeyB.IndexID)
require.Equal(t, roachpb.IndexUsageStatistics{}, stats, "expecting empty stats on node 1, but found %v", stats)

// Third node should have nothing.
stats = firstLocalStatsReader.Get(indexKeyPrimary.TableID, indexKeyPrimary.IndexID)
require.Equal(t, roachpb.IndexUsageStatistics{}, stats, "expecting empty stats on node 3, but found %v", stats)

stats = thirdLocalStatsReader.Get(indexKeyA.TableID, indexKeyA.IndexID)
require.Equal(t, roachpb.IndexUsageStatistics{}, stats, "expecting empty stats on node 3, but found %v", stats)

stats = thirdLocalStatsReader.Get(indexKeyB.TableID, indexKeyB.IndexID)
require.Equal(t, roachpb.IndexUsageStatistics{}, stats, "expecting empty stats on node 1, but found %v", stats)

// Second server should have nonempty local storage.
stats = secondLocalStatsReader.Get(indexKeyPrimary.TableID, indexKeyPrimary.IndexID)
compareStatsHelper(t, expectedStatsIndexPrimary, stats, time.Minute)

stats = secondLocalStatsReader.Get(indexKeyA.TableID, indexKeyA.IndexID)
compareStatsHelper(t, expectedStatsIndexA, stats, time.Minute)

Expand All @@ -196,14 +215,16 @@ func TestStatusAPIIndexUsage(t *testing.T) {
}
statsEntries++
switch stats.Key.IndexID {
case indexKeyPrimary.IndexID: // t@t_pkey
compareStatsHelper(t, expectedStatsIndexPrimary, stats.Stats, time.Minute)
case indexKeyA.IndexID: // t@t_a_idx
compareStatsHelper(t, expectedStatsIndexA, stats.Stats, time.Minute)
case indexKeyB.IndexID: // t@t_b_idx
compareStatsHelper(t, expectedStatsIndexB, stats.Stats, time.Minute)
}
}

require.True(t, statsEntries == 2, "expect to find two stats entries in RPC response, but found %d", statsEntries)
require.Equal(t, 3, statsEntries, "expect to find 3 stats entries in RPC response, but found %d", statsEntries)

// Test disabling subsystem.
_, err = secondServerSQLConn.Exec("SET CLUSTER SETTING sql.metrics.index_usage_stats.enabled = false")
Expand Down Expand Up @@ -231,5 +252,5 @@ func TestStatusAPIIndexUsage(t *testing.T) {
compareStatsHelper(t, expectedStatsIndexB, stats.Stats, time.Minute)
}
}
require.True(t, statsEntries == 2, "expect to find two stats entries in RPC response, but found %d", statsEntries)
require.Equal(t, 3, statsEntries, "expect to find 3 stats entries in RPC response, but found %d", statsEntries)
}
11 changes: 10 additions & 1 deletion pkg/sql/opt_exec_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -612,9 +612,18 @@ func (ef *execFactory) ConstructIndexJoin(
return nil, err
}

tableScan.index = tabDesc.GetPrimaryIndex()
idx := tabDesc.GetPrimaryIndex()
tableScan.index = idx
tableScan.disableBatchLimit()

if !ef.isExplain {
idxUsageKey := roachpb.IndexUsageKey{
TableID: roachpb.TableID(tabDesc.GetID()),
IndexID: roachpb.IndexID(idx.GetID()),
}
ef.planner.extendedEvalCtx.indexUsageStats.RecordRead(idxUsageKey)
}

n := &indexJoinNode{
input: input.(planNode),
table: tableScan,
Expand Down

0 comments on commit d608a0e

Please sign in to comment.