diff --git a/pkg/sql/exec_util.go b/pkg/sql/exec_util.go index 0dfb85233cfa..0adf792e0872 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_search.enabled", + "default value for locality_optimized_search session setting;"+ + "disables locality optimized search by default", + 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..3fc5bc1016da 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_search 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..0a08a9ea607c 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_search 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_search 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_search 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..110635bf9d3b 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_search 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..98b4b6f622d1 100644 --- a/pkg/sql/vars.go +++ b/pkg/sql/vars.go @@ -673,6 +673,25 @@ var varGen = map[string]sessionVar{ }, }, + // CockroachDB extension. + `locality_optimized_search`: { + GetStringVal: makePostgresBoolGetStringValFn(`locality_optimized_search`), + Set: func(_ context.Context, m *sessionDataMutator, s string) error { + b, err := paramparse.ParseBoolVar(`locality_optimized_search`, 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`),