From 1f724eb791a170f6ac2ae9e34ef4b31a341f29de Mon Sep 17 00:00:00 2001 From: Rebecca Taft Date: Thu, 18 Feb 2021 20:19:42 -0700 Subject: [PATCH] sql,opt: add cluster and session settings for locality optimized search This commit adds a new session setting locality_optimized_partitioned_index_scan and corresponding cluster default setting sql.defaults.locality_optimized_partitioned_index_scan.enabled. In future commits, these settings will be used to enable or disable locality optimized search. If enabled, the optimizer will try to plan scans and lookup joins in which local nodes are searched for matching rows before remote nodes, in the hope that the execution engine can avoid visiting remote nodes. Informs #55185 Release note (sql change): Added a new session setting locality_optimized_partitioned_index_scan and corresponding cluster default setting sql.defaults.locality_optimized_partitioned_index_scan.enabled. Both are currently disabled by default, and are currently unused. In the future, these settings will be used to enable or disable locality optimized search. If enabled, the optimizer will try to search locally for rows in REGIONAL BY ROW tables before searching remote nodes. --- pkg/sql/exec_util.go | 16 ++++++++++++++++ .../testdata/logic_test/information_schema | 1 + .../logictest/testdata/logic_test/pg_catalog | 3 +++ .../logictest/testdata/logic_test/show_source | 1 + pkg/sql/opt/memo/memo.go | 3 +++ pkg/sql/opt/memo/memo_test.go | 6 ++++++ pkg/sql/opt/optbuilder/builder_test.go | 1 + pkg/sql/opt/testutils/opttester/opt_tester.go | 1 + pkg/sql/sessiondata/session_data.go | 5 +++++ pkg/sql/vars.go | 19 +++++++++++++++++++ 10 files changed, 56 insertions(+) diff --git a/pkg/sql/exec_util.go b/pkg/sql/exec_util.go index 0dfb85233cfa..edc4ec78bfd2 100644 --- a/pkg/sql/exec_util.go +++ b/pkg/sql/exec_util.go @@ -286,6 +286,18 @@ var optUseMultiColStatsClusterMode = settings.RegisterBoolSetting( true, ) +// localityOptimizedSearchMode controls the cluster default for the use of +// locality optimized search. If enabled, the optimizer will try to plan scans +// and lookup joins in which local nodes (i.e., nodes in the gateway region) are +// searched for matching rows before remote nodes, in the hope that the +// execution engine can avoid visiting remote nodes. +var localityOptimizedSearchMode = settings.RegisterBoolSetting( + "sql.defaults.locality_optimized_partitioned_index_scan.enabled", + "default value for locality_optimized_partitioned_index_scan session setting; "+ + "enables searching for rows in the current region before searching remote regions", + false, +) + var implicitSelectForUpdateClusterMode = settings.RegisterBoolSetting( "sql.defaults.implicit_select_for_update.enabled", "default value for enable_implicit_select_for_update session setting; enables FOR UPDATE locking during the row-fetch phase of mutation statements", @@ -2192,6 +2204,10 @@ func (m *sessionDataMutator) SetOptimizerUseMultiColStats(val bool) { m.data.OptimizerUseMultiColStats = val } +func (m *sessionDataMutator) SetLocalityOptimizedSearch(val bool) { + m.data.LocalityOptimizedSearch = val +} + func (m *sessionDataMutator) SetImplicitSelectForUpdate(val bool) { m.data.ImplicitSelectForUpdate = val } diff --git a/pkg/sql/logictest/testdata/logic_test/information_schema b/pkg/sql/logictest/testdata/logic_test/information_schema index e74bf5812088..2cb038c27dbe 100755 --- a/pkg/sql/logictest/testdata/logic_test/information_schema +++ b/pkg/sql/logictest/testdata/logic_test/information_schema @@ -3462,6 +3462,7 @@ idle_in_transaction_session_timeout 0 integer_datetimes on intervalstyle postgres locality region=test,dc=dc1 +locality_optimized_partitioned_index_scan off lock_timeout 0 max_identifier_length 128 max_index_keys 32 diff --git a/pkg/sql/logictest/testdata/logic_test/pg_catalog b/pkg/sql/logictest/testdata/logic_test/pg_catalog index e060a20f9352..435a4c7ce7f5 100644 --- a/pkg/sql/logictest/testdata/logic_test/pg_catalog +++ b/pkg/sql/logictest/testdata/logic_test/pg_catalog @@ -2017,6 +2017,7 @@ idle_in_transaction_session_timeout 0 NULL integer_datetimes on NULL NULL NULL string intervalstyle postgres NULL NULL NULL string locality region=test,dc=dc1 NULL NULL NULL string +locality_optimized_partitioned_index_scan off NULL NULL NULL string lock_timeout 0 NULL NULL NULL string max_identifier_length 128 NULL NULL NULL string max_index_keys 32 NULL NULL NULL string @@ -2094,6 +2095,7 @@ idle_in_transaction_session_timeout 0 NULL integer_datetimes on NULL user NULL on on intervalstyle postgres NULL user NULL postgres postgres locality region=test,dc=dc1 NULL user NULL region=test,dc=dc1 region=test,dc=dc1 +locality_optimized_partitioned_index_scan off NULL user NULL off off lock_timeout 0 NULL user NULL 0 0 max_identifier_length 128 NULL user NULL 128 128 max_index_keys 32 NULL user NULL 32 32 @@ -2167,6 +2169,7 @@ idle_in_transaction_session_timeout NULL NULL NULL integer_datetimes NULL NULL NULL NULL NULL intervalstyle NULL NULL NULL NULL NULL locality NULL NULL NULL NULL NULL +locality_optimized_partitioned_index_scan NULL NULL NULL NULL NULL lock_timeout NULL NULL NULL NULL NULL max_identifier_length NULL NULL NULL NULL NULL max_index_keys NULL NULL NULL NULL NULL diff --git a/pkg/sql/logictest/testdata/logic_test/show_source b/pkg/sql/logictest/testdata/logic_test/show_source index 2b4ca2dde365..4e317ce5569a 100644 --- a/pkg/sql/logictest/testdata/logic_test/show_source +++ b/pkg/sql/logictest/testdata/logic_test/show_source @@ -62,6 +62,7 @@ idle_in_transaction_session_timeout 0 integer_datetimes on intervalstyle postgres locality region=test,dc=dc1 +locality_optimized_partitioned_index_scan off lock_timeout 0 max_identifier_length 128 max_index_keys 32 diff --git a/pkg/sql/opt/memo/memo.go b/pkg/sql/opt/memo/memo.go index d531fe62506e..0a3d4f4e004f 100644 --- a/pkg/sql/opt/memo/memo.go +++ b/pkg/sql/opt/memo/memo.go @@ -135,6 +135,7 @@ type Memo struct { zigzagJoinEnabled bool useHistograms bool useMultiColStats bool + localityOptimizedSearch bool safeUpdates bool preferLookupJoinsForFKs bool saveTablesPrefix string @@ -173,6 +174,7 @@ func (m *Memo) Init(evalCtx *tree.EvalContext) { zigzagJoinEnabled: evalCtx.SessionData.ZigzagJoinEnabled, useHistograms: evalCtx.SessionData.OptimizerUseHistograms, useMultiColStats: evalCtx.SessionData.OptimizerUseMultiColStats, + localityOptimizedSearch: evalCtx.SessionData.LocalityOptimizedSearch, safeUpdates: evalCtx.SessionData.SafeUpdates, preferLookupJoinsForFKs: evalCtx.SessionData.PreferLookupJoinsForFKs, saveTablesPrefix: evalCtx.SessionData.SaveTablesPrefix, @@ -281,6 +283,7 @@ func (m *Memo) IsStale( m.zigzagJoinEnabled != evalCtx.SessionData.ZigzagJoinEnabled || m.useHistograms != evalCtx.SessionData.OptimizerUseHistograms || m.useMultiColStats != evalCtx.SessionData.OptimizerUseMultiColStats || + m.localityOptimizedSearch != evalCtx.SessionData.LocalityOptimizedSearch || m.safeUpdates != evalCtx.SessionData.SafeUpdates || m.preferLookupJoinsForFKs != evalCtx.SessionData.PreferLookupJoinsForFKs || m.saveTablesPrefix != evalCtx.SessionData.SaveTablesPrefix { diff --git a/pkg/sql/opt/memo/memo_test.go b/pkg/sql/opt/memo/memo_test.go index 6b3506401cb0..0fa90c84e1e7 100644 --- a/pkg/sql/opt/memo/memo_test.go +++ b/pkg/sql/opt/memo/memo_test.go @@ -204,6 +204,12 @@ func TestMemoIsStale(t *testing.T) { evalCtx.SessionData.OptimizerUseMultiColStats = false notStale() + // Stale locality optimized search enable. + evalCtx.SessionData.LocalityOptimizedSearch = true + stale() + evalCtx.SessionData.LocalityOptimizedSearch = false + notStale() + // Stale safe updates. evalCtx.SessionData.SafeUpdates = true stale() diff --git a/pkg/sql/opt/optbuilder/builder_test.go b/pkg/sql/opt/optbuilder/builder_test.go index f0ed4b20c704..79a6f641f777 100644 --- a/pkg/sql/opt/optbuilder/builder_test.go +++ b/pkg/sql/opt/optbuilder/builder_test.go @@ -78,6 +78,7 @@ func TestBuilder(t *testing.T) { evalCtx := tree.MakeTestingEvalContext(cluster.MakeTestingClusterSettings()) evalCtx.SessionData.OptimizerUseHistograms = true evalCtx.SessionData.OptimizerUseMultiColStats = true + evalCtx.SessionData.LocalityOptimizedSearch = true var o xform.Optimizer o.Init(&evalCtx, catalog) diff --git a/pkg/sql/opt/testutils/opttester/opt_tester.go b/pkg/sql/opt/testutils/opttester/opt_tester.go index 98961c3be3ef..a28efd9fef31 100644 --- a/pkg/sql/opt/testutils/opttester/opt_tester.go +++ b/pkg/sql/opt/testutils/opttester/opt_tester.go @@ -244,6 +244,7 @@ func New(catalog cat.Catalog, sql string) *OptTester { ot.evalCtx.SessionData.ZigzagJoinEnabled = true ot.evalCtx.SessionData.OptimizerUseHistograms = true ot.evalCtx.SessionData.OptimizerUseMultiColStats = true + ot.evalCtx.SessionData.LocalityOptimizedSearch = true ot.evalCtx.SessionData.ReorderJoinsLimit = opt.DefaultJoinOrderLimit ot.evalCtx.SessionData.InsertFastPath = true diff --git a/pkg/sql/sessiondata/session_data.go b/pkg/sql/sessiondata/session_data.go index 815b2c9ad475..0119b35b2826 100644 --- a/pkg/sql/sessiondata/session_data.go +++ b/pkg/sql/sessiondata/session_data.go @@ -178,6 +178,11 @@ type LocalOnlySessionData struct { // OptimizerUseMultiColStats indicates whether we should use multi-column // statistics for cardinality estimation in the optimizer. OptimizerUseMultiColStats bool + // LocalityOptimizedSearch indicates that the optimizer will try to plan scans + // and lookup joins in which local nodes (i.e., nodes in the gateway region) + // are searched for matching rows before remote nodes, in the hope that the + // execution engine can avoid visiting remote nodes. + LocalityOptimizedSearch bool // SafeUpdates causes errors when the client // sends syntax that may have unwanted side effects. SafeUpdates bool diff --git a/pkg/sql/vars.go b/pkg/sql/vars.go index 1925e7ed3a24..8d3b7906cf6f 100644 --- a/pkg/sql/vars.go +++ b/pkg/sql/vars.go @@ -673,6 +673,25 @@ var varGen = map[string]sessionVar{ }, }, + // CockroachDB extension. + `locality_optimized_partitioned_index_scan`: { + GetStringVal: makePostgresBoolGetStringValFn(`locality_optimized_partitioned_index_scan`), + Set: func(_ context.Context, m *sessionDataMutator, s string) error { + b, err := paramparse.ParseBoolVar(`locality_optimized_partitioned_index_scan`, s) + if err != nil { + return err + } + m.SetLocalityOptimizedSearch(b) + return nil + }, + Get: func(evalCtx *extendedEvalContext) string { + return formatBoolAsPostgresSetting(evalCtx.SessionData.LocalityOptimizedSearch) + }, + GlobalDefault: func(sv *settings.Values) string { + return formatBoolAsPostgresSetting(localityOptimizedSearchMode.Get(sv)) + }, + }, + // CockroachDB extension. `enable_implicit_select_for_update`: { GetStringVal: makePostgresBoolGetStringValFn(`enable_implicit_select_for_update`),