diff --git a/.gitignore b/.gitignore index bd21bcef47c6d..9d902d837e3fa 100644 --- a/.gitignore +++ b/.gitignore @@ -78,3 +78,7 @@ var # Personal config files /*config.toml .cache + +# Claude Code runtime state (per-user, not part of repo) +.claude/scheduled_tasks.lock +.claude/settings.local.json diff --git a/pkg/bindinfo/binding_auto_test.go b/pkg/bindinfo/binding_auto_test.go index c150182247463..13953f3a68540 100644 --- a/pkg/bindinfo/binding_auto_test.go +++ b/pkg/bindinfo/binding_auto_test.go @@ -16,12 +16,14 @@ package bindinfo_test import ( "fmt" + "slices" "strings" "testing" "github.com/pingcap/tidb/pkg/bindinfo" "github.com/pingcap/tidb/pkg/parser" "github.com/pingcap/tidb/pkg/parser/auth" + "github.com/pingcap/tidb/pkg/sessionctx/vardef" "github.com/pingcap/tidb/pkg/testkit" "github.com/pingcap/tidb/pkg/testkit/testdata" "github.com/stretchr/testify/require" @@ -211,6 +213,30 @@ func TestRelevantOptVarsAndFixes(t *testing.T) { } } +func TestRelevantOptVarsCorrelateSubquery(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec(`create table t1 (a int, b int, key(a))`) + tk.MustExec(`create table t2 (a int, b int, key(a))`) + + p := parser.New() + sql := "select * from t1 where a in (select a from t2)" + + // The alternative logical plans variable is recorded as relevant because the + // code path where it affects plan choice (correlate-to-Apply) was reached. + for _, enabled := range []string{"OFF", "ON"} { + tk.MustExec("set tidb_opt_enable_alternative_logical_plans = " + enabled) + p.Reset() + stmt, err := p.ParseOneStmt(sql, "", "") + require.NoError(t, err) + vars, _, err := bindinfo.RecordRelevantOptVarsAndFixes(tk.Session(), stmt) + require.NoError(t, err) + require.True(t, slices.Contains(vars, vardef.TiDBOptEnableAlternativeLogicalPlans), + "enabled=%s: expected %s in recorded vars %v", enabled, vardef.TiDBOptEnableAlternativeLogicalPlans, vars) + } +} + func TestExplainExploreAnalyze(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) diff --git a/pkg/bindinfo/binding_plan_generation.go b/pkg/bindinfo/binding_plan_generation.go index 83dfd8887c9bc..2f7fd13833f4b 100644 --- a/pkg/bindinfo/binding_plan_generation.go +++ b/pkg/bindinfo/binding_plan_generation.go @@ -406,6 +406,8 @@ func genPlanUnderState(sctx sessionctx.Context, stmt ast.StmtNode, state *state) sctx.GetSessionVars().EnableSemiJoinRewrite = state.varValues[i].(bool) case vardef.TiDBOptSelectivityFactor: sctx.GetSessionVars().SelectivityFactor = state.varValues[i].(float64) + case vardef.TiDBOptEnableAlternativeLogicalPlans: + sctx.GetSessionVars().EnableAlternativeLogicalPlans = state.varValues[i].(bool) default: return nil, fmt.Errorf("unsupported variable %s in plan generation", varName) } @@ -507,7 +509,7 @@ func adjustVar(varName string, varVal any) (newVarVal any, err error) { } // increase 0.1 each step return v + 0.1, nil - case vardef.TiDBOptPreferRangeScan, vardef.TiDBOptEnableNoDecorrelateInSelect, vardef.TiDBOptAlwaysKeepJoinKey, vardef.TiDBOptEnableSemiJoinRewrite: // flip the switch + case vardef.TiDBOptPreferRangeScan, vardef.TiDBOptEnableNoDecorrelateInSelect, vardef.TiDBOptAlwaysKeepJoinKey, vardef.TiDBOptEnableSemiJoinRewrite, vardef.TiDBOptEnableAlternativeLogicalPlans: // flip the switch return !varVal.(bool), nil } return nil, fmt.Errorf("unsupported variable %s in plan generation", varName) @@ -600,6 +602,8 @@ func getStartState(vars []string, fixes []uint64, indexHintCount int) (*state, e s.varValues = append(s.varValues, vardef.DefOptSelectivityFactor) case vardef.TiDBOptCartesianJoinOrderThreshold: s.varValues = append(s.varValues, vardef.DefOptCartesianJoinOrderThreshold) + case vardef.TiDBOptEnableAlternativeLogicalPlans: + s.varValues = append(s.varValues, vardef.DefOptEnableAlternativeLogicalPlans) default: return nil, fmt.Errorf("unsupported variable %s in plan generation", varName) } diff --git a/pkg/ddl/ingest/BUILD.bazel b/pkg/ddl/ingest/BUILD.bazel index be5358cc2b9de..e978c4d8ad000 100644 --- a/pkg/ddl/ingest/BUILD.bazel +++ b/pkg/ddl/ingest/BUILD.bazel @@ -68,8 +68,11 @@ go_library( go_test( name = "ingest_internal_test", size = "small", + timeout = "short", srcs = ["engine_mgr_test.go"], embed = [":ingest"], + flaky = True, + shard_count = 32, deps = [ "//pkg/lightning/backend", "//pkg/meta/model", @@ -82,22 +85,24 @@ go_test( timeout = "moderate", srcs = [ "checkpoint_test.go", + "engine_mgr_test.go", "env_test.go", "integration_test.go", "main_test.go", "mem_root_test.go", ], + embed = [":ingest"], flaky = True, race = "on", shard_count = 31, deps = [ - ":ingest", "//pkg/config", "//pkg/config/kerneltype", "//pkg/ddl/ingest/testutil", "//pkg/ddl/session", "//pkg/ddl/testutil", "//pkg/errno", + "//pkg/lightning/backend", "//pkg/meta/model", "//pkg/testkit", "//pkg/testkit/testfailpoint", diff --git a/pkg/dxf/importinto/BUILD.bazel b/pkg/dxf/importinto/BUILD.bazel index a3585823ca911..bef393ef0252f 100644 --- a/pkg/dxf/importinto/BUILD.bazel +++ b/pkg/dxf/importinto/BUILD.bazel @@ -111,7 +111,7 @@ go_test( ], embed = [":importinto"], flaky = True, - shard_count = 31, + shard_count = 42, deps = [ "//pkg/config", "//pkg/config/kerneltype", @@ -144,9 +144,11 @@ go_test( "//pkg/objstore/storeapi", "//pkg/parser", "//pkg/parser/ast", + "//pkg/parser/mysql", "//pkg/planner/core", "//pkg/resourcemanager/pool/workerpool", "//pkg/session", + "//pkg/sessionctx", "//pkg/store", "//pkg/store/driver/error", "//pkg/store/mockstore", diff --git a/pkg/dxf/importinto/conflictedkv/BUILD.bazel b/pkg/dxf/importinto/conflictedkv/BUILD.bazel index 1ef907693d969..62713cc0f097d 100644 --- a/pkg/dxf/importinto/conflictedkv/BUILD.bazel +++ b/pkg/dxf/importinto/conflictedkv/BUILD.bazel @@ -50,7 +50,7 @@ go_test( ], embed = [":conflictedkv"], flaky = True, - shard_count = 6, + shard_count = 7, deps = [ "//pkg/config/kerneltype", "//pkg/executor/importer", diff --git a/pkg/executor/importer/BUILD.bazel b/pkg/executor/importer/BUILD.bazel index a2d4461b99d0d..94bcd7c06ebfc 100644 --- a/pkg/executor/importer/BUILD.bazel +++ b/pkg/executor/importer/BUILD.bazel @@ -116,7 +116,7 @@ go_test( embed = [":importer"], flaky = True, race = "on", - shard_count = 35, + shard_count = 42, deps = [ "//br/pkg/mock", "//br/pkg/streamhelper", diff --git a/pkg/expression/BUILD.bazel b/pkg/expression/BUILD.bazel index fb0bf49e8e68e..edf0f72c4460a 100644 --- a/pkg/expression/BUILD.bazel +++ b/pkg/expression/BUILD.bazel @@ -64,6 +64,7 @@ go_library( "expression.go", "extension.go", "fts_helper.go", + "fts_to_like.go", "function_traits.go", "grouping_sets.go", "helper.go", @@ -199,6 +200,7 @@ go_test( "evaluator_test.go", "expr_to_pb_test.go", "expression_test.go", + "fts_to_like_test.go", "function_traits_test.go", "grouping_sets_test.go", "helper_test.go", diff --git a/pkg/expression/builtin_fts.go b/pkg/expression/builtin_fts.go index 90d7bd819abc3..5a8fd80c9ee8a 100644 --- a/pkg/expression/builtin_fts.go +++ b/pkg/expression/builtin_fts.go @@ -196,8 +196,10 @@ func (c *ftsMysqlMatchAgainstFunctionClass) getFunction(ctx BuildContext, args [ func (b *builtinFtsMysqlMatchAgainstSig) evalReal(ctx EvalContext, row chunk.Row) (float64, bool, error) { // Matching NULL returns 0. - if b.args[0].(*Constant).Value.IsNull() { - return 0, false, nil + // args[0] is validated to be a *Constant by getFunction; guard defensively + // since the sig may be reconstructed via the distsql path without that check. + if constArg, ok := b.args[0].(*Constant); ok && constArg.Value.IsNull() { + return 0, true, nil } // Reject executing match against in TiDB side return 0, false, errors.Errorf("cannot use 'MATCH ... AGAINST' outside of fulltext index") diff --git a/pkg/expression/distsql_builtin.go b/pkg/expression/distsql_builtin.go index ba6f7e3835090..eb78681131811 100644 --- a/pkg/expression/distsql_builtin.go +++ b/pkg/expression/distsql_builtin.go @@ -1158,6 +1158,13 @@ func getSignatureByPB(ctx BuildContext, sigCode tipb.ScalarFuncSig, tp *tipb.Fie f = &builtinVecL2NormSig{base} case tipb.ScalarFuncSig_FTSMatchWord: f = &builtinFtsMatchWordSig{base} + case tipb.ScalarFuncSig_FTSMatchExpression: + // NOTE: builtinFtsMysqlMatchAgainstSig.modifier is not serialized in the + // protobuf encoding because the tipb schema has no FTS metadata message. + // The reconstructed sig therefore uses the zero modifier value + // (FulltextSearchModifierNaturalLanguageMode). TiFlash must derive the + // search mode from other context when executing this expression. + f = &builtinFtsMysqlMatchAgainstSig{baseBuiltinFunc: base} default: e = ErrFunctionNotExists.GenWithStackByArgs("FUNCTION", sigCode) return nil, e diff --git a/pkg/expression/fts_to_like.go b/pkg/expression/fts_to_like.go new file mode 100644 index 0000000000000..19e46dbbbe075 --- /dev/null +++ b/pkg/expression/fts_to_like.go @@ -0,0 +1,438 @@ +// Copyright 2026 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package expression + +import ( + "strings" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb/pkg/parser/ast" + "github.com/pingcap/tidb/pkg/parser/mysql" + "github.com/pingcap/tidb/pkg/types" +) + +// ftsSearchTerm represents a single token in a boolean-mode FTS search string +// surviving the strict-subset validator: a plain alphanumeric word optionally +// prefixed with `+` (required) or `-` (excluded). +type ftsSearchTerm struct { + word string + isRequired bool + isExcluded bool +} + +// parseFTSBooleanSearchString splits a boolean-mode search string into terms. +// Inputs reach this function only after ValidateFTSSearchStringForLikeFallback +// has accepted them, so every whitespace-separated field is either a bare +// alphanumeric word or `+word`/`-word`. +func parseFTSBooleanSearchString(text string) []ftsSearchTerm { + fields := strings.Fields(text) + if len(fields) == 0 { + return nil + } + terms := make([]ftsSearchTerm, 0, len(fields)) + for _, w := range fields { + terms = append(terms, parseFTSSearchTerm(w)) + } + return terms +} + +// parseFTSSearchTerm parses a single boolean-mode token. The strict-subset +// validator guarantees `word`, `+word`, or `-word` with an alphanumeric body, +// so only the leading operator needs interpretation. +func parseFTSSearchTerm(word string) ftsSearchTerm { + if word == "" { + return ftsSearchTerm{} + } + switch word[0] { + case '+': + return ftsSearchTerm{word: word[1:], isRequired: true} + case '-': + return ftsSearchTerm{word: word[1:], isExcluded: true} + } + return ftsSearchTerm{word: word} +} + +// isFTSWordByte returns true for alphanumeric ASCII and non-ASCII bytes. +// Punctuation including underscore is NOT a word character, consistent with +// MySQL's built-in FTS tokenizer which treats _ as a word separator. Used by +// ValidateFTSSearchStringForLikeFallback to gate the LIKE rewrite. +func isFTSWordByte(c byte) bool { + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c > 127 +} + +// escapeFTSLikePattern escapes special LIKE characters (%, _, \) in the search term +// so they are treated as literal characters rather than wildcards. +func escapeFTSLikePattern(term string) string { + // Count special characters to pre-allocate the exact buffer size needed + escapeCount := 0 + for i := range len(term) { + ch := term[i] + if ch == '\\' || ch == '%' || ch == '_' { + escapeCount++ + } + } + + // Allocate exact size: original length + number of escape characters + var result strings.Builder + result.Grow(len(term) + escapeCount) + for i := range len(term) { + ch := term[i] + if ch == '\\' || ch == '%' || ch == '_' { + result.WriteByte('\\') + } + result.WriteByte(ch) + } + return result.String() +} + +// ValidateFTSSearchStringForLikeFallback reports whether searchText falls +// inside the strict subset that the LIKE fallback is allowed to translate. +// The supported subset is, by mode: +// +// - Boolean mode: each whitespace-separated token must be `word`, `+word`, +// or `-word`, where `word` consists of ASCII alphanumeric characters or +// non-ASCII UTF-8 bytes (the same definition used by isFTSWordByte). +// - Natural-language mode: each whitespace-separated token must be a `word` +// of the same alphanumeric form (no leading +/- operators). +// +// An empty or whitespace-only search string is valid; BuildFTSToILikeExpression +// short-circuits to a constant-0 result for it. +// +// Anything outside this subset (phrases, * prefix, > < ~ relevance modifiers, +// () grouping, mid-word punctuation like `xx-yy`, etc.) is rejected because +// MySQL FTS tokenizes those constructs in ways that differ from a substring +// LIKE match. The planner uses this signal to skip the LIKE fallback for +// rejected strings; the native FTSMysqlMatchAgainst builtin can still serve +// the query when an FTS index is available. +func ValidateFTSSearchStringForLikeFallback(searchText string, modifier ast.FulltextSearchModifier) error { + isBoolean := modifier.IsBooleanMode() + for _, token := range strings.Fields(searchText) { + body := token + // strings.Fields never returns an empty token (consecutive whitespace + // is collapsed), so body[0] is safe today. Keep the len(body) > 0 + // guard explicit so the indexing is obviously bounded and the check + // stays correct if the tokenization ever changes. + if isBoolean && len(body) > 0 && (body[0] == '+' || body[0] == '-') { + body = body[1:] + } + if body == "" { + return ErrNotSupportedYet.GenWithStackByArgs( + "MATCH...AGAINST search term '" + token + "' is not supported in the LIKE fallback") + } + for i := range len(body) { + if !isFTSWordByte(body[i]) { + return ErrNotSupportedYet.GenWithStackByArgs( + "MATCH...AGAINST search term '" + token + "' is not supported in the LIKE fallback") + } + } + } + return nil +} + +// BuildFTSToILikeExpression converts a MATCH...AGAINST input (a list of column +// expressions, the search-string literal, and the parsed modifier) into an +// equivalent ILIKE-based predicate expression. +// +// Two callers share this conversion: +// - the planner's MATCH...AGAINST LIKE fallback rewrite, used by the +// "fts-like-fallback" alternative round when round 1 reports that the +// native FTSMysqlMatchAgainst builtin cannot serve a predicate-context +// MATCH (no FTS index on a TiFlash replica, modifier not pushdown-supported); +// - selectivity estimation, which substitutes the same ILIKE form for the +// opaque FTSMysqlMatchAgainst builtin so round 1's cost is computed from +// column statistics rather than a flat default — the native builtin +// cannot be evaluated in TiDB and would otherwise fall through to a +// SelectivityFactor (0.8) that ignores the column's histogram. +// +// Returns an integer (0/1) typed expression suitable for direct use as a +// filter predicate. +// +// Semantic differences from MySQL's full-text search are documented in detail +// at the planner-level call site; this helper preserves those approximations +// so both callers see the same translated expression. +func BuildFTSToILikeExpression( + ctx BuildContext, + columns []Expression, + searchText string, + modifier ast.FulltextSearchModifier, +) (Expression, error) { + if len(columns) == 0 { + return nil, ErrNotSupportedYet.GenWithStackByArgs("MATCH...AGAINST with no columns") + } + + // WITH QUERY EXPANSION requires a second FTS pass to find semantically related + // terms; LIKE cannot approximate this. Error explicitly rather than silently + // producing wrong results. + if modifier.WithQueryExpansion() { + return nil, ErrNotSupportedYet.GenWithStackByArgs("MATCH...AGAINST WITH QUERY EXPANSION is not supported in the LIKE fallback") + } + + // Reject search strings outside the strict supported subset before we + // translate. Callers that want a graceful fallback (e.g. the planner + // redirecting to the native builtin, or selectivity estimation falling + // through to a default estimate) should call this validator directly and + // react to its error. + if err := ValidateFTSSearchStringForLikeFallback(searchText, modifier); err != nil { + return nil, err + } + + if searchText == "" { + return ftsZeroIntConst(), nil + } + + if modifier.IsBooleanMode() { + return buildFTSBooleanModeILikeExpression(ctx, columns, searchText) + } + if modifier.IsNaturalLanguageMode() { + return buildFTSNaturalLanguageModeILikeExpression(ctx, columns, searchText) + } + return nil, ErrNotSupportedYet.GenWithStackByArgs("MATCH...AGAINST modifier is not supported in the LIKE fallback") +} + +// ftsZeroIntConst returns the constant-0 tiny-int expression used whenever +// the LIKE fallback can prove no row will match (empty search string, all +// terms tokenized away, or boolean-mode "only excluded" queries). +func ftsZeroIntConst() Expression { + return &Constant{ + Value: types.NewIntDatum(0), + RetType: types.NewFieldType(mysql.TypeTiny), + } +} + +// buildFTSBooleanModeILikeExpression handles `IN BOOLEAN MODE`. Required +// terms become an AND of per-term column-DNFs, excluded terms become NOT over +// per-term column-DNFs, and optional terms anchor the result only when no +// required terms exist (since LIKE cannot rank). +func buildFTSBooleanModeILikeExpression(ctx BuildContext, columns []Expression, searchText string) (Expression, error) { + terms := parseFTSBooleanSearchString(searchText) + if len(terms) == 0 { + return ftsZeroIntConst(), nil + } + + var required, excluded, optional []ftsSearchTerm + for _, term := range terms { + if term.word == "" { + continue + } + if term.isRequired { + required = append(required, term) + } else if term.isExcluded { + excluded = append(excluded, term) + } else { + optional = append(optional, term) + } + } + + // MySQL Boolean mode: a query with only excluded terms ("-a -b") returns + // an empty result set. The LIKE fallback must match this: when there are + // no required and no optional terms, no row can possibly satisfy the + // search, so return a constant FALSE immediately. + if len(required) == 0 && len(optional) == 0 && len(excluded) > 0 { + return ftsZeroIntConst(), nil + } + + var allPredicates []Expression + + // For each required term: (col1 ILIKE %term% OR col2 ILIKE %term% ...) + for _, term := range required { + var termColumnPreds []Expression + for _, column := range columns { + pred, err := buildFTSILikePredicate(ctx, column, term.word) + if err != nil { + return nil, err + } + termColumnPreds = append(termColumnPreds, pred) + } + if len(termColumnPreds) > 0 { + allPredicates = append(allPredicates, ComposeDNFCondition(ctx, termColumnPreds...)) + } + } + + // For each excluded term: NOT(col1 ILIKE %term% OR col2 ILIKE %term% ...) + for _, term := range excluded { + var termColumnPreds []Expression + for _, column := range columns { + pred, err := buildFTSILikePredicate(ctx, column, term.word) + if err != nil { + return nil, err + } + termColumnPreds = append(termColumnPreds, pred) + } + if len(termColumnPreds) > 0 { + notPred, err := NewFunction(ctx, ast.UnaryNot, types.NewFieldType(mysql.TypeTiny), + ComposeDNFCondition(ctx, termColumnPreds...)) + if err != nil { + return nil, err + } + allPredicates = append(allPredicates, notPred) + } + } + + // For optional terms: since LIKE cannot rank, treat optionals as a + // positive filter when no required terms exist. + // - required>0: ignore optionals (required terms already anchor the result) + // - required==0, excluded==0: at least one optional must match (pure optional query) + // - required==0, excluded>0: at least one optional must match AND excluded terms + // must be absent; AND the optional-DNF into allPredicates below + if len(optional) > 0 && len(required) == 0 { + var allOptionalPreds []Expression + for _, term := range optional { + for _, column := range columns { + pred, err := buildFTSILikePredicate(ctx, column, term.word) + if err != nil { + return nil, err + } + allOptionalPreds = append(allOptionalPreds, pred) + } + } + if len(allOptionalPreds) > 0 { + optionalDNF := ComposeDNFCondition(ctx, allOptionalPreds...) + if len(excluded) == 0 { + return optionalDNF, nil + } + allPredicates = append(allPredicates, optionalDNF) + } + } + + if len(allPredicates) == 0 { + return ftsZeroIntConst(), nil + } + + return ComposeCNFCondition(ctx, allPredicates...), nil +} + +// buildFTSNaturalLanguageModeILikeExpression handles the default +// natural-language mode by splitting the search string into whitespace +// tokens and OR-ing per-column per-word ILIKE predicates together. +func buildFTSNaturalLanguageModeILikeExpression(ctx BuildContext, columns []Expression, searchText string) (Expression, error) { + words := strings.Fields(searchText) + if len(words) == 0 { + return ftsZeroIntConst(), nil + } + + var columnPredicates []Expression + for _, column := range columns { + var wordPredicates []Expression + for _, word := range words { + pred, err := buildFTSILikePredicate(ctx, column, word) + if err != nil { + return nil, err + } + wordPredicates = append(wordPredicates, pred) + } + if len(wordPredicates) > 0 { + columnPredicates = append(columnPredicates, ComposeDNFCondition(ctx, wordPredicates...)) + } + } + + if len(columnPredicates) == 0 { + return ftsZeroIntConst(), nil + } + + return ComposeDNFCondition(ctx, columnPredicates...), nil +} + +// BuildFTSToILikeExpressionFromBuiltin pulls the search string and modifier +// out of a MATCH...AGAINST scalar function (FTSMysqlMatchAgainst) and +// delegates to BuildFTSToILikeExpression. It is the entry point for +// selectivity estimation, where the FTS scalar function is opaque to the +// stats engine; substituting an equivalent ILIKE expression lets the engine +// reuse its TopN/histogram-based estimation paths instead of falling back +// to a flat default that ignores column statistics. +// +// Restricted to single-column MATCH: GetSelectivityByFilter only estimates +// expressions over a single column, so a multi-column substituted ILIKE would +// be declined by the stats engine and fall through to the same str-match +// default that the un-substituted FTS expression already receives. Returning +// an error for the multi-column case lets the selectivity caller's existing +// err-check fall through cleanly, without producing a substitute that would +// never improve the estimate. +func BuildFTSToILikeExpressionFromBuiltin(ctx BuildContext, fts *ScalarFunction) (Expression, error) { + if fts == nil || fts.FuncName.L != ast.FTSMysqlMatchAgainst { + return nil, errors.Errorf("expected %s, got %v", ast.FTSMysqlMatchAgainst, fts) + } + args := fts.GetArgs() + if len(args) < 2 { + return nil, errors.Errorf("%s expects at least 2 args, got %d", ast.FTSMysqlMatchAgainst, len(args)) + } + if len(args) > 2 { + return nil, ErrNotSupportedYet.GenWithStackByArgs("multi-column MATCH...AGAINST in selectivity substitution") + } + againstConst, ok := args[0].(*Constant) + if !ok { + return nil, ErrNotSupportedYet.GenWithStackByArgs("MATCH...AGAINST with non-constant search string") + } + if againstConst.Value.IsNull() { + // Match the planner-side matchAgainstToLike NULL fast-path: emit + // Constant(NULL) so the substitute preserves SQL three-valued logic + // even though selectivity estimation does not currently exploit the + // difference. Constant(0) here would, under any future cost path that + // composes NOT over the substitute, report "NOT 0 = TRUE → selectivity + // 1" — opposite of native MATCH(NULL) which returns NULL. + return &Constant{ + Value: types.Datum{}, + RetType: types.NewFieldType(mysql.TypeTiny), + }, nil + } + if againstConst.Value.Kind() != types.KindString { + return nil, ErrNotSupportedYet.GenWithStackByArgs("MATCH...AGAINST with non-string search constant") + } + sig, ok := fts.Function.(*builtinFtsMysqlMatchAgainstSig) + if !ok { + return nil, errors.Errorf("unexpected builtin signature for %s: %T", ast.FTSMysqlMatchAgainst, fts.Function) + } + return BuildFTSToILikeExpression(ctx, args[1:], againstConst.Value.GetString(), sig.modifier) +} + +// buildFTSILikePredicate builds a single ILIKE predicate for a column and search term, +// wrapped in IFNULL so that NULL columns are treated as not containing the term. +func buildFTSILikePredicate(ctx BuildContext, column Expression, term string) (Expression, error) { + escapedTerm := escapeFTSLikePattern(term) + + // NOTE: Prefix matching (word*) in MySQL full-text search matches words that START with + // the prefix, but the word can appear anywhere in the text. Using LIKE without REGEXP, + // we cannot perfectly enforce word-start boundaries. We use %term% which may produce + // false positives but avoids false negatives. + pattern := "%" + escapedTerm + "%" + + patternConst := &Constant{ + Value: types.NewStringDatum(pattern), + RetType: types.NewFieldType(mysql.TypeVarchar), + } + + // Backslash escape character (=92) for ILIKE. + escapeConst := &Constant{ + Value: types.NewIntDatum(92), + RetType: types.NewFieldType(mysql.TypeTiny), + } + + // MySQL full-text search is always case-insensitive regardless of column + // collation, so ILIKE matches that semantic rather than plain LIKE which + // would follow the column's collation. + likeFunc, err := NewFunction(ctx, ast.Ilike, types.NewFieldType(mysql.TypeTiny), column, patternConst, escapeConst) + if err != nil { + return nil, err + } + + // Wrap with IFNULL so a NULL column is treated as not containing the term + // (consistent with MySQL FTS semantics where NULL columns are ignored). + // Without this, NOT(NULL ILIKE %term%) = NOT(NULL) = NULL which incorrectly + // filters rows that have a NULL column and don't contain the excluded term. + zeroConst := &Constant{ + Value: types.NewIntDatum(0), + RetType: types.NewFieldType(mysql.TypeTiny), + } + return NewFunction(ctx, ast.Ifnull, types.NewFieldType(mysql.TypeTiny), likeFunc, zeroConst) +} diff --git a/pkg/expression/fts_to_like_test.go b/pkg/expression/fts_to_like_test.go new file mode 100644 index 0000000000000..4f0581698c0a7 --- /dev/null +++ b/pkg/expression/fts_to_like_test.go @@ -0,0 +1,340 @@ +// Copyright 2026 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package expression + +import ( + "testing" + + "github.com/pingcap/tidb/pkg/parser/ast" + "github.com/pingcap/tidb/pkg/parser/mysql" + "github.com/pingcap/tidb/pkg/types" + "github.com/pingcap/tidb/pkg/util/mock" + "github.com/stretchr/testify/require" +) + +func TestValidateFTSSearchStringForLikeFallback(t *testing.T) { + naturalMode := ast.FulltextSearchModifier(ast.FulltextSearchModifierNaturalLanguageMode) + booleanMode := ast.FulltextSearchModifier(ast.FulltextSearchModifierBooleanMode) + + tests := []struct { + name string + text string + modifier ast.FulltextSearchModifier + wantErr bool + }{ + // Natural-language mode: plain alphanumeric words only. + {name: "natural empty", text: "", modifier: naturalMode, wantErr: false}, + {name: "natural whitespace only", text: " \t\n ", modifier: naturalMode, wantErr: false}, + {name: "natural single word", text: "MySQL", modifier: naturalMode, wantErr: false}, + {name: "natural multi word", text: "MySQL tutorial PostgreSQL", modifier: naturalMode, wantErr: false}, + {name: "natural alphanumeric mix", text: "abc123 mysql8", modifier: naturalMode, wantErr: false}, + {name: "natural rejects mid-word dash", text: "x-x", modifier: naturalMode, wantErr: true}, + {name: "natural rejects punctuation suffix", text: "MySQL,", modifier: naturalMode, wantErr: true}, + {name: "natural rejects + operator", text: "+word", modifier: naturalMode, wantErr: true}, + {name: "natural rejects - operator", text: "-word", modifier: naturalMode, wantErr: true}, + {name: "natural rejects quote", text: `"phrase"`, modifier: naturalMode, wantErr: true}, + {name: "natural rejects wildcard", text: "word*", modifier: naturalMode, wantErr: true}, + {name: "natural rejects percent", text: "100%", modifier: naturalMode, wantErr: true}, + {name: "natural rejects underscore", text: "test_file", modifier: naturalMode, wantErr: true}, + + // Boolean mode: plain word, +word, -word with alphanumeric body only. + {name: "boolean empty", text: "", modifier: booleanMode, wantErr: false}, + {name: "boolean plain word", text: "MySQL", modifier: booleanMode, wantErr: false}, + {name: "boolean required word", text: "+MySQL", modifier: booleanMode, wantErr: false}, + {name: "boolean excluded word", text: "-MySQL", modifier: booleanMode, wantErr: false}, + {name: "boolean mix", text: "+apple -cherry pie", modifier: booleanMode, wantErr: false}, + {name: "boolean rejects mid-word dash", text: "xx-yy", modifier: booleanMode, wantErr: true}, + {name: "boolean rejects bare operator", text: "+", modifier: booleanMode, wantErr: true}, + {name: "boolean rejects bare minus", text: "-", modifier: booleanMode, wantErr: true}, + {name: "boolean rejects + after body", text: "x+y", modifier: booleanMode, wantErr: true}, + {name: "boolean rejects wildcard", text: "word*", modifier: booleanMode, wantErr: true}, + {name: "boolean rejects required wildcard", text: "+word*", modifier: booleanMode, wantErr: true}, + {name: "boolean rejects relevance gt", text: ">word", modifier: booleanMode, wantErr: true}, + {name: "boolean rejects relevance lt", text: " 127 case). + {name: "natural utf8 word", text: "你好", modifier: naturalMode, wantErr: false}, + {name: "boolean utf8 word", text: "+你好", modifier: booleanMode, wantErr: false}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := ValidateFTSSearchStringForLikeFallback(tt.text, tt.modifier) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +// TestParseFTSBooleanSearchString covers the strict-subset inputs the boolean +// parser is expected to handle in production. Inputs outside the subset +// (phrases, wildcards, relevance modifiers, mid-word punctuation, etc.) are +// rejected upstream by ValidateFTSSearchStringForLikeFallback and therefore +// never reach this parser. +func TestParseFTSBooleanSearchString(t *testing.T) { + tests := []struct { + input string + expected []ftsSearchTerm + }{ + { + input: "+apple +pie", + expected: []ftsSearchTerm{ + {word: "apple", isRequired: true}, + {word: "pie", isRequired: true}, + }, + }, + { + input: "+apple -cherry", + expected: []ftsSearchTerm{ + {word: "apple", isRequired: true}, + {word: "cherry", isExcluded: true}, + }, + }, + { + input: "word1 word2 word3", + expected: []ftsSearchTerm{ + {word: "word1"}, + {word: "word2"}, + {word: "word3"}, + }, + }, + { + input: "word1\t\nword2", + expected: []ftsSearchTerm{ + {word: "word1"}, + {word: "word2"}, + }, + }, + { + input: "", + expected: nil, + }, + { + input: " \t\n ", + expected: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.input, func(t *testing.T) { + result := parseFTSBooleanSearchString(tt.input) + require.Equal(t, len(tt.expected), len(result), "Number of terms should match") + for i, expected := range tt.expected { + require.Equal(t, expected.word, result[i].word, "Word should match") + require.Equal(t, expected.isRequired, result[i].isRequired, "isRequired should match") + require.Equal(t, expected.isExcluded, result[i].isExcluded, "isExcluded should match") + } + }) + } +} + +func TestParseFTSSearchTerm(t *testing.T) { + tests := []struct { + input string + expected ftsSearchTerm + }{ + {input: "+word", expected: ftsSearchTerm{word: "word", isRequired: true}}, + {input: "-word", expected: ftsSearchTerm{word: "word", isExcluded: true}}, + {input: "word", expected: ftsSearchTerm{word: "word"}}, + {input: "", expected: ftsSearchTerm{}}, + // Bare operator with no body (caller passes the result through; the + // upstream validator rejects this case before the parser sees it). + {input: "+", expected: ftsSearchTerm{word: "", isRequired: true}}, + {input: "-", expected: ftsSearchTerm{word: "", isExcluded: true}}, + } + + for _, tt := range tests { + t.Run(tt.input, func(t *testing.T) { + result := parseFTSSearchTerm(tt.input) + require.Equal(t, tt.expected.word, result.word, "Word should match") + require.Equal(t, tt.expected.isRequired, result.isRequired, "isRequired should match") + require.Equal(t, tt.expected.isExcluded, result.isExcluded, "isExcluded should match") + }) + } +} + +func TestEscapeFTSLikePattern(t *testing.T) { + tests := []struct { + input string + expected string + }{ + { + input: "normal text", + expected: "normal text", + }, + { + input: "100%", + expected: "100\\%", + }, + { + input: "test_file", + expected: "test\\_file", + }, + { + input: "path\\to\\file", + expected: "path\\\\to\\\\file", + }, + { + input: "mix_%_all", + expected: "mix\\_\\%\\_all", + }, + { + input: "\\%_", + expected: "\\\\\\%\\_", + }, + { + input: "", + expected: "", + }, + } + + for _, tt := range tests { + t.Run(tt.input, func(t *testing.T) { + result := escapeFTSLikePattern(tt.input) + require.Equal(t, tt.expected, result, "Escaped pattern should match") + }) + } +} + +// newFTSMatchAgainstForTest builds a real FTSMysqlMatchAgainst ScalarFunction +// suitable for exercising BuildFTSToILikeExpressionFromBuiltin. It mirrors +// the planner's matchAgainstToBuiltin flow: build via NewFunction with a +// string Constant for AGAINST and one or more string Columns for MATCH, +// then attach the modifier via SetFTSMysqlMatchAgainstModifier. +func newFTSMatchAgainstForTest(t *testing.T, ctx BuildContext, search string, numCols int, modifier ast.FulltextSearchModifier) *ScalarFunction { + t.Helper() + stringTp := types.NewFieldType(mysql.TypeVarchar) + stringTp.SetCollate(mysql.DefaultCollationName) + args := make([]Expression, 0, 1+numCols) + args = append(args, &Constant{Value: types.NewStringDatum(search), RetType: stringTp}) + for i := range numCols { + args = append(args, &Column{Index: i, RetType: stringTp}) + } + fn, err := NewFunction(ctx, ast.FTSMysqlMatchAgainst, types.NewFieldType(mysql.TypeDouble), args...) + require.NoError(t, err) + sf, ok := fn.(*ScalarFunction) + require.True(t, ok) + require.NoError(t, SetFTSMysqlMatchAgainstModifier(sf, modifier)) + return sf +} + +func TestBuildFTSToILikeExpressionFromBuiltin(t *testing.T) { + ctx := mock.NewContext() + naturalMode := ast.FulltextSearchModifier(ast.FulltextSearchModifierNaturalLanguageMode) + + t.Run("nil scalar function", func(t *testing.T) { + _, err := BuildFTSToILikeExpressionFromBuiltin(ctx, nil) + require.Error(t, err) + }) + + t.Run("wrong function name", func(t *testing.T) { + // Construct a non-FTS ScalarFunction by reusing one we know exists. + stringTp := types.NewFieldType(mysql.TypeVarchar) + col := &Column{Index: 0, RetType: stringTp} + other, err := NewFunction(ctx, ast.Length, types.NewFieldType(mysql.TypeLonglong), col) + require.NoError(t, err) + _, err = BuildFTSToILikeExpressionFromBuiltin(ctx, other.(*ScalarFunction)) + require.Error(t, err) + require.Contains(t, err.Error(), ast.FTSMysqlMatchAgainst) + }) + + t.Run("single-column natural-language succeeds", func(t *testing.T) { + sf := newFTSMatchAgainstForTest(t, ctx, "mysql", 1, naturalMode) + expr, err := BuildFTSToILikeExpressionFromBuiltin(ctx, sf) + require.NoError(t, err) + require.NotNil(t, expr) + // The result should be a scalar function (IFNULL(ILIKE,...)) — not the + // untranslated FTS opaque builtin. + resultSF, ok := expr.(*ScalarFunction) + require.True(t, ok) + require.NotEqual(t, ast.FTSMysqlMatchAgainst, resultSF.FuncName.L) + }) + + t.Run("multi-column rejected for selectivity substitution", func(t *testing.T) { + // GetSelectivityByFilter declines expressions over more than one column, + // so a multi-column substituted ILIKE would never improve the estimate. + // BuildFTSToILikeExpressionFromBuiltin returns an error to keep that + // path explicit; the selectivity caller's err-check then falls through + // to the str-match default cleanly. + sf := newFTSMatchAgainstForTest(t, ctx, "mysql", 2, naturalMode) + _, err := BuildFTSToILikeExpressionFromBuiltin(ctx, sf) + require.Error(t, err) + require.Contains(t, err.Error(), "multi-column") + }) + + t.Run("NULL search constant returns Constant(NULL)", func(t *testing.T) { + // The builtin's getFunction allows NULL search constants explicitly + // (builtin_fts.go:129); the substitution short-circuits to Constant(NULL) + // rather than Constant(0) so it composes correctly under SQL three-valued + // logic and matches the planner-side matchAgainstToLike NULL fast-path. + stringTp := types.NewFieldType(mysql.TypeVarchar) + nullArg := &Constant{Value: types.NewDatum(nil), RetType: stringTp} + col := &Column{Index: 0, RetType: stringTp} + fn, err := NewFunction(ctx, ast.FTSMysqlMatchAgainst, types.NewFieldType(mysql.TypeDouble), nullArg, col) + require.NoError(t, err) + sf := fn.(*ScalarFunction) + require.NoError(t, SetFTSMysqlMatchAgainstModifier(sf, naturalMode)) + + expr, err := BuildFTSToILikeExpressionFromBuiltin(ctx, sf) + require.NoError(t, err) + c, ok := expr.(*Constant) + require.True(t, ok) + require.True(t, c.Value.IsNull(), "expected Constant(NULL), got %v", c.Value) + }) + + t.Run("search string outside strict subset rejected", func(t *testing.T) { + // Search string with mid-word `-` fails ValidateFTSSearchStringForLikeFallback + // and propagates that rejection through BuildFTSToILikeExpression. + sf := newFTSMatchAgainstForTest(t, ctx, "xx-yy", 1, naturalMode) + _, err := BuildFTSToILikeExpressionFromBuiltin(ctx, sf) + require.Error(t, err) + }) +} + +func TestScalarExprSupportedByFlashRejectsNonDefaultFTSModifier(t *testing.T) { + // The tipb pushdown protocol does not serialize the FTS modifier; TiFlash + // reconstructs the signature with the default (natural-language) modifier. + // scalarExprSupportedByFlash must therefore mark non-default-modifier + // FTSMysqlMatchAgainst as NOT Flash-supported even though the function + // name is generally Flash-pushdown-eligible. This is defense in depth on + // top of the planner's modifier guard in matchAgainstToBuiltin. + ctx := mock.NewContext() + naturalMode := ast.FulltextSearchModifier(ast.FulltextSearchModifierNaturalLanguageMode) + booleanMode := ast.FulltextSearchModifier(ast.FulltextSearchModifierBooleanMode) + queryExpansion := ast.FulltextSearchModifier(ast.FulltextSearchModifierNaturalLanguageMode | ast.FulltextSearchModifierWithQueryExpansion) + + cases := []struct { + name string + modifier ast.FulltextSearchModifier + want bool + }{ + {"natural-language mode is Flash-supported", naturalMode, true}, + {"boolean mode is not Flash-supported", booleanMode, false}, + {"with-query-expansion is not Flash-supported", queryExpansion, false}, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + sf := newFTSMatchAgainstForTest(t, ctx, "mysql", 1, tc.modifier) + require.Equal(t, tc.want, scalarExprSupportedByFlash(ctx.GetEvalCtx(), sf)) + }) + } +} diff --git a/pkg/expression/infer_pushdown.go b/pkg/expression/infer_pushdown.go index aef3b5fa9871d..54527c54aa4c8 100644 --- a/pkg/expression/infer_pushdown.go +++ b/pkg/expression/infer_pushdown.go @@ -452,6 +452,18 @@ func scalarExprSupportedByFlash(ctx EvalContext, function *ScalarFunction) bool return true case ast.FTSMatchWord: return true + case ast.FTSMysqlMatchAgainst: + // The tipb pushdown protocol (see distsql_builtin.go) does not + // serialize the FTS modifier; TiFlash defaults to natural-language + // mode on the reconstructed signature. Pushing a Boolean-mode or + // WITH QUERY EXPANSION call down would therefore silently execute + // with the modifier dropped. Mark such calls as not Flash-supported + // here as a defense in depth — the planner's modifier guard in + // matchAgainstToBuiltin already rejects them at plan time, but + // keeping pushdown self-consistent guards against any future code + // path that builds an FTSMysqlMatchAgainst around the planner. + sig, ok := function.Function.(*builtinFtsMysqlMatchAgainstSig) + return ok && !sig.modifier.IsBooleanMode() && !sig.modifier.WithQueryExpansion() case ast.Grouping: // grouping function for grouping sets identification. return true } diff --git a/pkg/expression/integration_test/integration_test.go b/pkg/expression/integration_test/integration_test.go index dfd2d9b91a655..a3ccf25f031e3 100644 --- a/pkg/expression/integration_test/integration_test.go +++ b/pkg/expression/integration_test/integration_test.go @@ -231,7 +231,14 @@ func TestFTSSyntax(t *testing.T) { // tk.MustContainErrMsg("select * from t where (fts_match_word('hello', title)) > 0", "Currently 'FTS_MATCH_WORD()' must be used alone") // tk.MustContainErrMsg("select (fts_match_word('hello', title)) AS score from t where fts_match_word('hello', title)", "Currently 'FTS_MATCH_WORD()' cannot be used in SELECT fields") tk.MustContainErrMsg("select * from t where match() against ('hello')", `You have an error in your SQL syntax`) + tk.MustContainErrMsg("select * from t where match(title) against ('hello' in boolean mode)", `cannot use 'MATCH ... AGAINST' outside of fulltext index`) + + // Test MATCH...AGAINST with alternative plans - LIKE fallback competes on cost + tk.MustExec("set @@tidb_opt_enable_alternative_logical_plans=ON") + tk.MustQuery("select * from t where match(title) against ('hello' in boolean mode)") + tk.MustExec("set @@tidb_opt_enable_alternative_logical_plans=OFF") + tk.MustContainErrMsg("select * from t where fts_match_word(title, body)", `match against a non-constant string`) tk.MustContainErrMsg("select * from t where fts_match_word(45.67, body)", `match against a non-constant string`) tk.MustContainErrMsg("select * from t where fts_match_word('hello', title, body)", `Full text search can only be used with a matching fulltext index`) diff --git a/pkg/planner/BUILD.bazel b/pkg/planner/BUILD.bazel index a9f1721d0a552..a0adbf6a9ef97 100644 --- a/pkg/planner/BUILD.bazel +++ b/pkg/planner/BUILD.bazel @@ -14,6 +14,7 @@ go_library( "//pkg/planner/core", "//pkg/planner/core/base", "//pkg/planner/core/resolve", + "//pkg/planner/core/rule", "//pkg/planner/indexadvisor", "//pkg/planner/planctx", "//pkg/planner/property", @@ -28,9 +29,11 @@ go_library( "//pkg/util/dbterror/plannererrors", "//pkg/util/hint", "//pkg/util/intest", + "//pkg/util/logutil", "//pkg/util/topsql", "//pkg/util/tracing", "@com_github_pingcap_errors//:errors", "@com_github_pingcap_failpoint//:failpoint", + "@org_uber_go_zap//:zap", ], ) diff --git a/pkg/planner/cardinality/selectivity.go b/pkg/planner/cardinality/selectivity.go index 131fe07abc5e5..c70f388c201e0 100644 --- a/pkg/planner/cardinality/selectivity.go +++ b/pkg/planner/cardinality/selectivity.go @@ -247,6 +247,48 @@ func Selectivity( case ast.Like, ast.Ilike, ast.Regexp, ast.RegexpLike: notCoveredStrMatch[i] = x continue + case ast.FTSMysqlMatchAgainst: + // FTSMysqlMatchAgainst is opaque to the stats engine — its + // evalReal errors when called outside TiFlash, so TopN-based + // estimation can't run on it directly and the generic fallback + // would use SelectivityFactor (0.8) regardless of column stats. + // Substitute the equivalent ILIKE-based expression so the cost + // of round 1's native plan reflects the column's histogram / + // TopN rather than the flat default — this affects join order, + // index selection, etc., even though round 1's plan is the + // only candidate when every predicate MATCH is native-viable + // (the fts-like-fallback round only fires when round 1 is + // discarded). + // + // The substitution only fires for single-column MATCH(...); + // GetSelectivityByFilter declines multi-column expressions, so a + // multi-column substitute would just fall through to the same + // str-match default that the un-substituted FTS expression already + // receives. BuildFTSToILikeExpressionFromBuiltin returns an error + // for the multi-column case to keep that path explicit here. + if substitute, err := expression.BuildFTSToILikeExpressionFromBuiltin(ctx.GetExprCtx(), x); err == nil { + switch sub := substitute.(type) { + case *expression.ScalarFunction: + notCoveredStrMatch[i] = sub + continue + case *expression.Constant: + // AGAINST(NULL) produces Constant(NULL) (preserves SQL + // three-valued logic — matches the planner-side + // matchAgainstToLike NULL fast-path); empty-string + // search produces Constant(0). Route either to the + // constants bucket so the stats engine recognizes the + // substitute as constant-false (the IsNull / ToBool + // pass at line ~309 zeroes selectivity for both + // shapes) instead of applying the str-match default + // (0.1). + notCoveredConstants[i] = sub + continue + } + } + // Fall through if substitution failed; the FTS expression will + // use the str-match default selectivity (0.1) instead of 0.8. + notCoveredStrMatch[i] = x + continue case ast.UnaryNot: inner := expression.GetExprInsideIsTruth(x.GetArgs()[0]) innerSF, ok := inner.(*expression.ScalarFunction) diff --git a/pkg/planner/core/BUILD.bazel b/pkg/planner/core/BUILD.bazel index 49eb8800ea04e..c8157bbe2aef6 100644 --- a/pkg/planner/core/BUILD.bazel +++ b/pkg/planner/core/BUILD.bazel @@ -18,6 +18,7 @@ go_library( "expression_rewriter.go", "find_best_task.go", "flat_plan.go", + "fulltext_to_like.go", "hint_utils.go", "index_join_path.go", "indexmerge_path.go", @@ -49,6 +50,7 @@ go_library( "rule_aggregation_elimination.go", "rule_aggregation_push_down.go", "rule_aggregation_skew_rewrite.go", + "rule_correlate.go", "rule_decorrelate.go", "rule_derive_topn_from_window.go", "rule_eliminate_empty_selection.go", @@ -217,6 +219,7 @@ go_test( "exhaust_physical_plans_test.go", "expression_test.go", "find_best_task_test.go", + "fulltext_to_like_test.go", "hint_test.go", "integration_test.go", "logical_plans_test.go", diff --git a/pkg/planner/core/base/BUILD.bazel b/pkg/planner/core/base/BUILD.bazel index b65d24049693c..d27bdd38f3ab9 100644 --- a/pkg/planner/core/base/BUILD.bazel +++ b/pkg/planner/core/base/BUILD.bazel @@ -24,6 +24,7 @@ go_library( "//pkg/types", "//pkg/util/collate", "//pkg/util/execdetails", + "//pkg/util/intest", "@com_github_pingcap_tipb//go-tipb", ], ) diff --git a/pkg/planner/core/base/misc_base.go b/pkg/planner/core/base/misc_base.go index 8505c03ea702e..a25e2372b5c1c 100644 --- a/pkg/planner/core/base/misc_base.go +++ b/pkg/planner/core/base/misc_base.go @@ -106,3 +106,30 @@ type PartitionAccesser interface { type PartitionTable interface { PartitionExpr() *tables.PartitionExpr } + +// FTSLikeFallbackError marks a native full-text-search planning error that can +// be retried through the MATCH...AGAINST-to-LIKE fallback round when +// alternative logical plans are enabled for a direct-boolean predicate context. +// +// The optimizer unwraps this back to Cause whenever no fallback round is +// available, so users still see the original error message in non-fallback +// scenarios. +type FTSLikeFallbackError struct { + Cause error +} + +// Error implements the error interface. +func (e *FTSLikeFallbackError) Error() string { + if e == nil || e.Cause == nil { + return "" + } + return e.Cause.Error() +} + +// Unwrap returns the original native-FTS error. +func (e *FTSLikeFallbackError) Unwrap() error { + if e == nil { + return nil + } + return e.Cause +} diff --git a/pkg/planner/core/base/plan_base.go b/pkg/planner/core/base/plan_base.go index bbe222befeac0..bde8c7bc0af59 100644 --- a/pkg/planner/core/base/plan_base.go +++ b/pkg/planner/core/base/plan_base.go @@ -26,6 +26,7 @@ import ( "github.com/pingcap/tidb/pkg/planner/util/costusage" "github.com/pingcap/tidb/pkg/types" "github.com/pingcap/tidb/pkg/util/execdetails" + "github.com/pingcap/tidb/pkg/util/intest" "github.com/pingcap/tipb/go-tipb" ) @@ -321,6 +322,17 @@ const ( AntiLeftOuterSemiJoin ) +// NOTE: keep JoinType value unchanged, because they are used in conflict_detector.go +func init() { + intest.Assert(InnerJoin == 0 && + LeftOuterJoin == 1 && + RightOuterJoin == 2 && + SemiJoin == 3 && + AntiSemiJoin == 4 && + LeftOuterSemiJoin == 5 && + AntiLeftOuterSemiJoin == 6) +} + // IsOuterJoin returns if this joiner is an outer joiner func (tp JoinType) IsOuterJoin() bool { return tp == LeftOuterJoin || tp == RightOuterJoin || diff --git a/pkg/planner/core/casetest/binaryplan/testdata/binary_plan_suite_out.json b/pkg/planner/core/casetest/binaryplan/testdata/binary_plan_suite_out.json index 36408143c7ad1..3edd94e8de0f0 100644 --- a/pkg/planner/core/casetest/binaryplan/testdata/binary_plan_suite_out.json +++ b/pkg/planner/core/casetest/binaryplan/testdata/binary_plan_suite_out.json @@ -68,19 +68,19 @@ "SQL": "explain analyze format = 'binary' select sum(t.a) from t join t2", "BinaryPlan": { "main": { - "name": "HashAgg_12", + "name": "HashAgg_13", "children": [ { - "name": "Projection_60", + "name": "Projection_61", "children": [ { - "name": "HashJoin_31", + "name": "HashJoin_32", "children": [ { - "name": "IndexReader_36", + "name": "IndexReader_37", "children": [ { - "name": "IndexFullScan_35", + "name": "IndexFullScan_36", "cost": 1628000.000001, "est_rows": 10000, "act_rows": 2, @@ -97,13 +97,13 @@ "act_rows": 2, "task_type": 1, "store_type": 1, - "operator_info": "index:IndexFullScan_35" + "operator_info": "index:IndexFullScan_36" }, { - "name": "TableReader_38", + "name": "TableReader_39", "children": [ { - "name": "TableFullScan_37", + "name": "TableFullScan_38", "cost": 4546159.475587022, "est_rows": 10000, "act_rows": 4, @@ -120,7 +120,7 @@ "act_rows": 4, "task_type": 1, "store_type": 1, - "operator_info": "data:TableFullScan_37" + "operator_info": "data:TableFullScan_38" } ], "cost": 1128387.631705868, diff --git a/pkg/planner/core/casetest/binaryplan/testdata/binary_plan_suite_xut.json b/pkg/planner/core/casetest/binaryplan/testdata/binary_plan_suite_xut.json index 8d54458ef2653..5064f2e2ca333 100644 --- a/pkg/planner/core/casetest/binaryplan/testdata/binary_plan_suite_xut.json +++ b/pkg/planner/core/casetest/binaryplan/testdata/binary_plan_suite_xut.json @@ -68,19 +68,19 @@ "SQL": "explain analyze format = 'binary' select sum(t.a) from t join t2", "BinaryPlan": { "main": { - "name": "HashAgg_12", + "name": "HashAgg_13", "children": [ { - "name": "Projection_60", + "name": "Projection_61", "children": [ { - "name": "HashJoin_31", + "name": "HashJoin_32", "children": [ { - "name": "IndexReader_36", + "name": "IndexReader_37", "children": [ { - "name": "IndexFullScan_35", + "name": "IndexFullScan_36", "cost": 1628000.000001, "est_rows": 10000, "act_rows": 2, @@ -97,13 +97,13 @@ "act_rows": 2, "task_type": 1, "store_type": 1, - "operator_info": "index:IndexFullScan_35" + "operator_info": "index:IndexFullScan_36" }, { - "name": "TableReader_38", + "name": "TableReader_39", "children": [ { - "name": "TableFullScan_37", + "name": "TableFullScan_38", "cost": 4546159.475587022, "est_rows": 10000, "act_rows": 4, @@ -120,7 +120,7 @@ "act_rows": 4, "task_type": 1, "store_type": 1, - "operator_info": "data:TableFullScan_37" + "operator_info": "data:TableFullScan_38" } ], "cost": 1128387.631705868, diff --git a/pkg/planner/core/casetest/cbotest/testdata/analyze_suite_out.json b/pkg/planner/core/casetest/cbotest/testdata/analyze_suite_out.json index c5dce27a1299f..8168f0ef72fef 100644 --- a/pkg/planner/core/casetest/cbotest/testdata/analyze_suite_out.json +++ b/pkg/planner/core/casetest/cbotest/testdata/analyze_suite_out.json @@ -260,7 +260,7 @@ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", "└─IndexReader(Probe) 12475.01 root index:Selection", " └─Selection 12475.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.c))", - " └─IndexRangeScan 12500.00 cop[tikv] table:t2, index:idx(a, b, c) range: decided by [eq(test.t2.a, test.t1.a) lt(test.t2.b, plus(test.t1.b, 1)) gt(test.t2.b, minus(test.t1.b, 1))], keep order:false, stats:pseudo" + " └─IndexRangeScan 12500.00 cop[tikv] table:t2, index:idx(a, b, c) range: decided by [eq(test.t2.a, test.t1.a) gt(test.t2.b, minus(test.t1.b, 1)) lt(test.t2.b, plus(test.t1.b, 1))], keep order:false, stats:pseudo" ] }, { diff --git a/pkg/planner/core/casetest/cbotest/testdata/analyze_suite_xut.json b/pkg/planner/core/casetest/cbotest/testdata/analyze_suite_xut.json index c5dce27a1299f..8168f0ef72fef 100644 --- a/pkg/planner/core/casetest/cbotest/testdata/analyze_suite_xut.json +++ b/pkg/planner/core/casetest/cbotest/testdata/analyze_suite_xut.json @@ -260,7 +260,7 @@ "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", "└─IndexReader(Probe) 12475.01 root index:Selection", " └─Selection 12475.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.c))", - " └─IndexRangeScan 12500.00 cop[tikv] table:t2, index:idx(a, b, c) range: decided by [eq(test.t2.a, test.t1.a) lt(test.t2.b, plus(test.t1.b, 1)) gt(test.t2.b, minus(test.t1.b, 1))], keep order:false, stats:pseudo" + " └─IndexRangeScan 12500.00 cop[tikv] table:t2, index:idx(a, b, c) range: decided by [eq(test.t2.a, test.t1.a) gt(test.t2.b, minus(test.t1.b, 1)) lt(test.t2.b, plus(test.t1.b, 1))], keep order:false, stats:pseudo" ] }, { diff --git a/pkg/planner/core/casetest/hint/testdata/integration_suite_out.json b/pkg/planner/core/casetest/hint/testdata/integration_suite_out.json index a2b22e1351727..e32bb993159fb 100644 --- a/pkg/planner/core/casetest/hint/testdata/integration_suite_out.json +++ b/pkg/planner/core/casetest/hint/testdata/integration_suite_out.json @@ -1921,9 +1921,7 @@ " └─TableReader(Probe) 10000.00 root data:TableFullScan", " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], - "Warn": [ - "Warning 1815 leading hint is inapplicable, check if the leading hint table has join conditions with other tables" - ] + "Warn": null } ] }, diff --git a/pkg/planner/core/casetest/hint/testdata/integration_suite_xut.json b/pkg/planner/core/casetest/hint/testdata/integration_suite_xut.json index a2b22e1351727..e32bb993159fb 100644 --- a/pkg/planner/core/casetest/hint/testdata/integration_suite_xut.json +++ b/pkg/planner/core/casetest/hint/testdata/integration_suite_xut.json @@ -1921,9 +1921,7 @@ " └─TableReader(Probe) 10000.00 root data:TableFullScan", " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], - "Warn": [ - "Warning 1815 leading hint is inapplicable, check if the leading hint table has join conditions with other tables" - ] + "Warn": null } ] }, diff --git a/pkg/planner/core/casetest/mpp/testdata/integration_suite_out.json b/pkg/planner/core/casetest/mpp/testdata/integration_suite_out.json index a668cbe17cbf2..c6cce919881e6 100644 --- a/pkg/planner/core/casetest/mpp/testdata/integration_suite_out.json +++ b/pkg/planner/core/casetest/mpp/testdata/integration_suite_out.json @@ -1705,23 +1705,22 @@ " │ └─Projection 10000.00 mpp[tiflash] test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, cast(test.t.c4, decimal(40,20))->Column#33", " │ └─TableFullScan 10000.00 mpp[tiflash] table:t4 keep order:false, stats:pseudo", " └─Projection(Probe) 15593.77 mpp[tiflash] test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5", - " └─Projection 15593.77 mpp[tiflash] test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5", - " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t.c5, test.t.c3)]", - " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", - " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#29, collate: binary]", - " │ └─Projection 10000.00 mpp[tiflash] test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, cast(test.t.c3, decimal(40,20))->Column#29", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo", - " └─ExchangeReceiver(Probe) 12475.01 mpp[tiflash] ", - " └─ExchangeSender 12475.01 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.c5, collate: binary]", - " └─HashJoin 12475.01 mpp[tiflash] inner join, equal:[eq(test.t.c2, test.t.c1)]", - " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", - " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.c2, collate: binary]", - " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t.c2)), not(isnull(test.t.c5))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", - " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", - " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.c1, collate: binary]", - " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.c1))", - " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t.c5, test.t.c3)]", + " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", + " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#29, collate: binary]", + " │ └─Projection 10000.00 mpp[tiflash] test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, cast(test.t.c3, decimal(40,20))->Column#29", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 12475.01 mpp[tiflash] ", + " └─ExchangeSender 12475.01 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.c5, collate: binary]", + " └─HashJoin 12475.01 mpp[tiflash] inner join, equal:[eq(test.t.c2, test.t.c1)]", + " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", + " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.c2, collate: binary]", + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t.c2)), not(isnull(test.t.c5))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.c1, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.c1))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" ] }, { diff --git a/pkg/planner/core/casetest/mpp/testdata/integration_suite_xut.json b/pkg/planner/core/casetest/mpp/testdata/integration_suite_xut.json index 48098a27e6a07..ae881da51fde8 100644 --- a/pkg/planner/core/casetest/mpp/testdata/integration_suite_xut.json +++ b/pkg/planner/core/casetest/mpp/testdata/integration_suite_xut.json @@ -1705,23 +1705,22 @@ " │ └─Projection 10000.00 mpp[tiflash] test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, cast(test.t.c4, decimal(40,20))->Column#33", " │ └─TableFullScan 10000.00 mpp[tiflash] table:t4 keep order:false, stats:pseudo", " └─Projection(Probe) 15593.77 mpp[tiflash] test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5", - " └─Projection 15593.77 mpp[tiflash] test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5", - " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t.c5, test.t.c3)]", - " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", - " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#29, collate: binary]", - " │ └─Projection 10000.00 mpp[tiflash] test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, cast(test.t.c3, decimal(40,20))->Column#29", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo", - " └─ExchangeReceiver(Probe) 12475.01 mpp[tiflash] ", - " └─ExchangeSender 12475.01 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.c5, collate: binary]", - " └─HashJoin 12475.01 mpp[tiflash] inner join, equal:[eq(test.t.c2, test.t.c1)]", - " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", - " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.c2, collate: binary]", - " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t.c2)), not(isnull(test.t.c5))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", - " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", - " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.c1, collate: binary]", - " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.c1))", - " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t.c5, test.t.c3)]", + " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", + " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: Column#29, collate: binary]", + " │ └─Projection 10000.00 mpp[tiflash] test.t.c1, test.t.c2, test.t.c3, test.t.c4, test.t.c5, cast(test.t.c3, decimal(40,20))->Column#29", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 12475.01 mpp[tiflash] ", + " └─ExchangeSender 12475.01 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.c5, collate: binary]", + " └─HashJoin 12475.01 mpp[tiflash] inner join, equal:[eq(test.t.c2, test.t.c1)]", + " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", + " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.c2, collate: binary]", + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t.c2)), not(isnull(test.t.c5))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 9990.00 mpp[tiflash] ", + " └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.c1, collate: binary]", + " └─Selection 9990.00 mpp[tiflash] not(isnull(test.t.c1))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" ] }, { diff --git a/pkg/planner/core/casetest/physicalplantest/physical_plan_test.go b/pkg/planner/core/casetest/physicalplantest/physical_plan_test.go index 3a8b15b90ae4f..1d11881977848 100644 --- a/pkg/planner/core/casetest/physicalplantest/physical_plan_test.go +++ b/pkg/planner/core/casetest/physicalplantest/physical_plan_test.go @@ -1583,7 +1583,7 @@ func TestLimitPushdown(t *testing.T) { tk.MustExec("create table t1(c1 int, c2 int, key(c1));") tk.MustExec("set @@cte_max_recursion_depth = 10000;") tk.MustExec("insert into t1 with recursive cte1 as (select 1 cola, 1 colb union all select cola+1 as cola, colb+1 as colb from cte1 limit 5000) select * from cte1;") - tk.MustExec("analyze table t1;") + tk.MustExec("analyze table t1 all columns;") var input []string var output []struct { diff --git a/pkg/planner/core/casetest/rule/BUILD.bazel b/pkg/planner/core/casetest/rule/BUILD.bazel index 08693ffe1908b..2a8c725cf78a0 100644 --- a/pkg/planner/core/casetest/rule/BUILD.bazel +++ b/pkg/planner/core/casetest/rule/BUILD.bazel @@ -6,6 +6,8 @@ go_test( srcs = [ "dual_test.go", "main_test.go", + "rule_cdc_join_reorder_test.go", + "rule_correlate_test.go", "rule_derive_topn_from_window_test.go", "rule_eliminate_empty_selection_test.go", "rule_eliminate_projection_test.go", @@ -18,7 +20,7 @@ go_test( ], data = glob(["testdata/**"]), flaky = True, - shard_count = 18, + shard_count = 27, deps = [ "//pkg/config", "//pkg/domain", diff --git a/pkg/planner/core/casetest/rule/main_test.go b/pkg/planner/core/casetest/rule/main_test.go index 29dc38057e3b8..722050484844b 100644 --- a/pkg/planner/core/casetest/rule/main_test.go +++ b/pkg/planner/core/casetest/rule/main_test.go @@ -35,6 +35,9 @@ func TestMain(m *testing.M) { testDataMap.LoadTestSuiteData("testdata", "predicate_pushdown_suite", true) testDataMap.LoadTestSuiteData("testdata", "predicate_simplification", true) testDataMap.LoadTestSuiteData("testdata", "outer_to_semi_join_suite", true) + testDataMap.LoadTestSuiteData("testdata", "correlate_suite", true) + testDataMap.LoadTestSuiteData("testdata", "cdc_join_reorder_suite", true) + testDataMap.LoadTestSuiteData("testdata", "order_aware_join_reorder_suite", true) opts := []goleak.Option{ goleak.IgnoreTopFunction("github.com/golang/glog.(*fileSink).flushDaemon"), @@ -77,3 +80,15 @@ func GetPredicateSimplificationSuiteData() testdata.TestData { func GetOuterToSemiJoinSuiteData() testdata.TestData { return testDataMap["outer_to_semi_join_suite"] } + +func GetCorrelateSuiteData() testdata.TestData { + return testDataMap["correlate_suite"] +} + +func GetCDCJoinReorderSuiteData() testdata.TestData { + return testDataMap["cdc_join_reorder_suite"] +} + +func GetOrderAwareJoinReorderSuiteData() testdata.TestData { + return testDataMap["order_aware_join_reorder_suite"] +} diff --git a/pkg/planner/core/casetest/rule/rule_cdc_join_reorder_test.go b/pkg/planner/core/casetest/rule/rule_cdc_join_reorder_test.go new file mode 100644 index 0000000000000..74f707dabfe42 --- /dev/null +++ b/pkg/planner/core/casetest/rule/rule_cdc_join_reorder_test.go @@ -0,0 +1,330 @@ +// Copyright 2026 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package rule + +import ( + "fmt" + "strings" + "testing" + + "github.com/pingcap/tidb/pkg/testkit" + "github.com/pingcap/tidb/pkg/testkit/testdata" + "github.com/stretchr/testify/require" +) + +func prepareOrderAwareJoinReorderTables(tk *testkit.TestKit) { + tk.MustExec("use test") + tk.MustExec("set @@tidb_opt_enable_alternative_logical_plans = 0") + tk.MustExec("drop table if exists t6, t7, t8, t9") + tk.MustExec("create table t6(id int not null, category varchar(20), payload int, key idx_id(id), key idx_category_id_payload(category, id, payload))") + tk.MustExec("create table t7(id int not null, payload int, key idx_id(id))") + tk.MustExec("create table t8(id int not null, payload int, key idx_id(id), key idx_payload_id(payload, id))") + tk.MustExec("create table t9(id int not null, payload int, key idx_id(id), key idx_payload_id(payload, id))") + + t6Rows := make([]string, 0, 8000) + t7Rows := make([]string, 0, 6000) + t8Rows := make([]string, 0, 7000) + t9Rows := make([]string, 0, 9000) + for i := 1; i <= 8000; i++ { + category := "cold" + if i <= 2000 { + category = "hot" + } + t6Rows = append(t6Rows, fmt.Sprintf("(%d,'%s',%d)", i, category, i*10)) + } + for i := 1; i <= 6000; i++ { + t7Rows = append(t7Rows, fmt.Sprintf("(%d,%d)", i, i*100)) + } + for i := 1; i <= 7000; i++ { + payload := 0 + if i <= 100 { + payload = 1 + } + t8Rows = append(t8Rows, fmt.Sprintf("(%d,%d)", i, payload)) + } + for i := 1; i <= 9000; i++ { + payload := 0 + if i <= 130 { + payload = 1 + } + t9Rows = append(t9Rows, fmt.Sprintf("(%d,%d)", i, payload)) + } + tk.MustExec("insert into t6 values " + strings.Join(t6Rows, ",")) + tk.MustExec("insert into t7 values " + strings.Join(t7Rows, ",")) + tk.MustExec("insert into t8 values " + strings.Join(t8Rows, ",")) + tk.MustExec("insert into t9 values " + strings.Join(t9Rows, ",")) + tk.MustExec("analyze table t6 all columns") + tk.MustExec("analyze table t7 all columns") + tk.MustExec("analyze table t8 all columns") + tk.MustExec("analyze table t9 all columns") +} + +func prepareOrderAwareAlternativeRoundTables(tk *testkit.TestKit) { + tk.MustExec("use test") + tk.MustExec("drop table if exists oa_order_t1, oa_order_t2, oa_order_t3, oa_order_t4, obj, relationship") + tk.MustExec("create table oa_order_t1(id int not null primary key, category varchar(20), created_at int, key idx_category_created(category, created_at, id))") + tk.MustExec("create table oa_order_t2(id int not null primary key, t1_id int not null, key idx_t1_id(t1_id))") + tk.MustExec("create table oa_order_t3(id int not null primary key, t2_id int not null, key idx_t2_id(t2_id))") + tk.MustExec("create table oa_order_t4(id int not null primary key, t3_id int not null, payload int, key idx_payload_t3(payload, t3_id))") + tk.MustExec("create table obj(id int not null, label varchar(32), workid varchar(32), type_id int, txt_val varchar(32), key idx_workid_label(workid, label), key idx_id(id), key idx_label(label))") + tk.MustExec("create table relationship(obj_id int, ref_ojb_id int, key idx_obj_id(obj_id, ref_ojb_id), key idx_ref_obj_id(ref_ojb_id, obj_id))") + + oaOrderT1Rows := make([]string, 0, 5000) + oaOrderT2Rows := make([]string, 0, 5000) + oaOrderT3Rows := make([]string, 0, 5000) + oaOrderT4Rows := make([]string, 0, 5000) + for i := 1; i <= 5000; i++ { + oaOrderT1Rows = append(oaOrderT1Rows, fmt.Sprintf("(%d,'hot',%d)", i, i)) + oaOrderT2Rows = append(oaOrderT2Rows, fmt.Sprintf("(%d,%d)", i, i)) + oaOrderT3Rows = append(oaOrderT3Rows, fmt.Sprintf("(%d,%d)", i, i)) + payload := 0 + if i%10 == 0 { + payload = 1 + } + oaOrderT4Rows = append(oaOrderT4Rows, fmt.Sprintf("(%d,%d,%d)", i, i, payload)) + } + tk.MustExec("insert into oa_order_t1 values " + strings.Join(oaOrderT1Rows, ",")) + tk.MustExec("insert into oa_order_t2 values " + strings.Join(oaOrderT2Rows, ",")) + tk.MustExec("insert into oa_order_t3 values " + strings.Join(oaOrderT3Rows, ",")) + tk.MustExec("insert into oa_order_t4 values " + strings.Join(oaOrderT4Rows, ",")) + // insert rows to obj and relationship. + tk.MustExec("SET SESSION cte_max_recursion_depth = 10000;") + tk.MustExec("INSERT INTO obj (id, label, workid, type_id, txt_val) " + + "SELECT n, CONCAT('label_', LPAD(CAST(FLOOR(RAND()*100000) AS CHAR), 5, '0'))," + + "CONCAT('w', LPAD(CAST(1 + FLOOR(RAND()*50) AS CHAR), 3, '0'))," + + "1 + FLOOR(RAND()*3)," + + "CONCAT('txt_', SUBSTRING(MD5(RAND()), 1, 12)) FROM ( WITH RECURSIVE seq(n) AS ( SELECT 1 UNION ALL SELECT n + 1 FROM seq WHERE n < 10000)" + + " SELECT n FROM seq ) s;") + + tk.MustExec("INSERT INTO relationship (obj_id, ref_ojb_id) SELECT obj_id, CASE WHEN obj_id = ref_ojb_id THEN IF(obj_id = 1000, 9999, obj_id + 1)" + + " ELSE ref_ojb_id END FROM ( WITH RECURSIVE seq(n) AS ( SELECT 1 UNION ALL SELECT n + 1 FROM seq WHERE n < 1000 ) " + + " SELECT 1 + FLOOR(RAND()*1000) AS obj_id, 1 + FLOOR(RAND()*1000) AS ref_ojb_id FROM seq) r;") + tk.MustExec("analyze table oa_order_t1 all columns") + tk.MustExec("analyze table oa_order_t2 all columns") + tk.MustExec("analyze table oa_order_t3 all columns") + tk.MustExec("analyze table oa_order_t4 all columns") + tk.MustExec("analyze table obj all columns") + tk.MustExec("analyze table relationship all columns") +} + +func TestCDCJoinReorder(tt *testing.T) { + testkit.RunTestUnderCascades(tt, func(t *testing.T, tk *testkit.TestKit, cascades, caller string) { + tk.MustExec("use test") + tk.MustExec("drop table if exists t1, t2, t3, t4, t5") + tk.MustExec("CREATE TABLE t1 (a INT, b INT)") + tk.MustExec("CREATE TABLE t2 (a INT, b INT)") + tk.MustExec("CREATE TABLE t3 (a INT, b INT)") + tk.MustExec("CREATE TABLE t4 (a INT, b INT)") + tk.MustExec("CREATE TABLE t5 (a INT, b INT)") + + tk.MustExec("INSERT INTO t1 VALUES (1, 10), (2, 20), (3, 30)") + tk.MustExec("INSERT INTO t2 VALUES (1, 100), (2, 200), (4, 400)") + tk.MustExec("INSERT INTO t3 VALUES (1, 1000), (3, 3000), (5, 5000)") + tk.MustExec("INSERT INTO t4 VALUES (1, 10000), (4, 40000), (6, 60000)") + tk.MustExec("INSERT INTO t5 VALUES (2, 20000), (5, 50000), (7, 70000)") + + tk.MustExec("analyze table t1 all columns;") + tk.MustExec("analyze table t2 all columns;") + tk.MustExec("analyze table t3 all columns;") + tk.MustExec("analyze table t4 all columns;") + tk.MustExec("analyze table t5 all columns;") + + var input []string + var output []struct { + SQL string + Plan []string + Result []string + } + suite := GetCDCJoinReorderSuiteData() + suite.LoadTestCases(t, &input, &output, cascades, caller) + + // Phase 1: Collect expected results using the old join reorder algorithm + // (CD-C is NOT enabled yet). These serve as the ground-truth baseline. + expectedResults := make([][]string, len(input)) + for i, sql := range input { + expectedResults[i] = testdata.ConvertRowsToStrings(tk.MustQuery(sql).Rows()) + } + + // Phase 2: Enable CD-C algorithm, then verify both the plan and the + // result correctness for every case. + for i, sql := range input { + testdata.OnRecord(func() { + output[i].SQL = sql + output[i].Plan = testdata.ConvertRowsToStrings(tk.MustQuery("EXPLAIN FORMAT='plan_tree' " + sql).Rows()) + output[i].Result = testdata.ConvertRowsToStrings(tk.MustQuery(sql).Rows()) + }) + tk.MustQuery("EXPLAIN FORMAT='plan_tree' " + sql).Check(testkit.Rows(output[i].Plan...)) + + // Run with CD-C and cross-validate against the old algorithm baseline. + cdcResult := testdata.ConvertRowsToStrings(tk.MustQuery(sql).Rows()) + require.Equalf(t, expectedResults[i], cdcResult, + "CD-C result differs from old algorithm for case[%d]: %s", i, sql) + } + }) +} + +func TestJoinReorderPushSelection(tt *testing.T) { + testkit.RunTestUnderCascades(tt, func(t *testing.T, tk *testkit.TestKit, cascades, caller string) { + tk.MustExec("use test") + tk.MustExec("drop table if exists t1, t2, t3, t4, t5") + tk.MustExec("create table t1(id int not null primary key, name varchar(100))") + tk.MustExec("create table t2(id int not null primary key, name varchar(100))") + tk.MustExec("create table t3(id int not null primary key, name varchar(100))") + tk.MustExec("create table t4(id int not null primary key, name varchar(100))") + tk.MustExec("create table t5(id int not null primary key, name varchar(100))") + tk.MustExec("set @@tidb_opt_join_reorder_through_sel = 1") + + tk.MustExec("insert into t1 values (1,'a'),(2,'b'),(3,'c')") + tk.MustExec("insert into t2 values (1,'a'),(2,'b'),(4,'d')") + tk.MustExec("insert into t3 values (1,'a'),(3,'c'),(5,'e')") + tk.MustExec("insert into t4 values (1,'a'),(4,'d'),(6,'f')") + tk.MustExec("insert into t5 values (2,'b'),(5,'e'),(7,'g')") + tk.MustExec("analyze table t1 all columns") + tk.MustExec("analyze table t2 all columns") + tk.MustExec("analyze table t3 all columns") + tk.MustExec("analyze table t4 all columns") + tk.MustExec("analyze table t5 all columns") + + var input []string + var output []struct { + SQL string + Plan []string + } + suite := GetCDCJoinReorderSuiteData() + suite.LoadTestCasesByName("TestJoinReorderPushSelection", t, &input, &output, cascades, caller) + + planCaseIdx := 0 + for _, sql := range input { + normalized := strings.ToLower(strings.TrimSpace(sql)) + if strings.HasPrefix(normalized, "set ") { + tk.MustExec(sql) + continue + } + + plan := tk.MustQuery(sql) + testdata.OnRecord(func() { + if planCaseIdx >= len(output) { + output = append(output, struct { + SQL string + Plan []string + }{}) + } + output[planCaseIdx].SQL = sql + output[planCaseIdx].Plan = testdata.ConvertRowsToStrings(plan.Rows()) + }) + + require.Lessf(t, planCaseIdx, len(output), + "missing expected output for plan case[%d], sql: %s", planCaseIdx, sql) + require.Equalf(t, sql, output[planCaseIdx].SQL, + "input/output SQL mismatch at plan case[%d]", planCaseIdx) + plan.Check(testkit.Rows(output[planCaseIdx].Plan...)) + planCaseIdx++ + } + require.Equalf(t, len(output), planCaseIdx, + "unexpected output case count, output=%d, actual explain cases=%d", len(output), planCaseIdx) + }) +} + +func TestOrderAwareJoinReorderPushSelection(tt *testing.T) { + testkit.RunTestUnderCascades(tt, func(t *testing.T, tk *testkit.TestKit, cascades, caller string) { + prepareOrderAwareJoinReorderTables(tk) + tk.MustExec("set @@tidb_opt_join_reorder_through_sel = 1") + + var input []string + var output []struct { + SQL string + Plan []string + } + suite := GetOrderAwareJoinReorderSuiteData() + suite.LoadTestCasesByName("TestOrderAwareJoinReorderPushSelection", t, &input, &output, cascades, caller) + + for i, sql := range input { + normalized := strings.ToLower(strings.TrimSpace(sql)) + if strings.HasPrefix(normalized, "set ") { + testdata.OnRecord(func() { + if i >= len(output) { + output = append(output, struct { + SQL string + Plan []string + }{}) + } + output[i].SQL = sql + output[i].Plan = nil + }) + require.Lessf(t, i, len(output), "missing expected output for case[%d], sql: %s", i, sql) + require.Equalf(t, sql, output[i].SQL, "input/output SQL mismatch at case[%d]", i) + tk.MustExec(sql) + continue + } + + testdata.OnRecord(func() { + if i >= len(output) { + output = append(output, struct { + SQL string + Plan []string + }{}) + } + output[i].SQL = sql + output[i].Plan = testdata.ConvertRowsToStrings(tk.MustQuery(sql).Rows()) + }) + require.Lessf(t, i, len(output), "missing expected output for case[%d], sql: %s", i, sql) + require.Equalf(t, sql, output[i].SQL, "input/output SQL mismatch at case[%d]", i) + tk.MustQuery(sql).Check(testkit.Rows(output[i].Plan...)) + require.NotContains(t, strings.Join(testdata.ConvertRowsToStrings(tk.MustQuery("show warnings").Rows()), "\n"), + "leading hint is inapplicable") + } + }) +} + +func TestOrderAwareJoinReorderAlternativeRound(tt *testing.T) { + testkit.RunTestUnderCascades(tt, func(t *testing.T, tk *testkit.TestKit, cascades, caller string) { + prepareOrderAwareAlternativeRoundTables(tk) + + var input []string + var output []struct { + SQL string + Plan []string + } + suite := GetOrderAwareJoinReorderSuiteData() + suite.LoadTestCasesByName("TestOrderAwareJoinReorderAlternativeRound", t, &input, &output, cascades, caller) + + expectedExplainCnt := 0 + for _, sql := range input { + normalized := strings.ToLower(strings.TrimSpace(sql)) + if !strings.HasPrefix(normalized, "set ") { + expectedExplainCnt++ + } + } + for i, sql := range input { + normalized := strings.ToLower(strings.TrimSpace(sql)) + if strings.HasPrefix(normalized, "set ") { + testdata.OnRecord(func() { + output[i].SQL = sql + output[i].Plan = nil + }) + require.Equalf(t, sql, output[i].SQL, "input/output SQL mismatch at case[%d]", i) + tk.MustExec(sql) + continue + } + + plan := tk.MustQuery(sql) + rows := testdata.ConvertRowsToStrings(plan.Rows()) + testdata.OnRecord(func() { + output[i].SQL = sql + output[i].Plan = rows + }) + } + }) +} diff --git a/pkg/planner/core/casetest/rule/rule_correlate_test.go b/pkg/planner/core/casetest/rule/rule_correlate_test.go new file mode 100644 index 0000000000000..0c3a1b61d2f0c --- /dev/null +++ b/pkg/planner/core/casetest/rule/rule_correlate_test.go @@ -0,0 +1,250 @@ +// Copyright 2026 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package rule + +import ( + "fmt" + "strings" + "testing" + + "github.com/pingcap/tidb/pkg/testkit" + "github.com/pingcap/tidb/pkg/testkit/testdata" + "github.com/stretchr/testify/require" +) + +// TestCorrelateNullSemantics verifies that CorrelateSolver does not break +// 3-valued NULL semantics for scalar IN (LeftOuterSemiJoin). +func TestCorrelateNullSemantics(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("set tidb_opt_enable_alternative_logical_plans = ON") + + // Case 1: non-null outer, null inner → must return NULL (not 0). + tk.MustExec("drop table if exists tn, sn") + tk.MustExec("create table tn(a int)") + tk.MustExec("create table sn(a int, key(a))") + tk.MustExec("insert into tn values (1)") + tk.MustExec("insert into sn values (null)") + tk.MustQuery("select tn.a in (select sn.a from sn) as r from tn").Check(testkit.Rows("")) + + // Case 2: null outer, non-null inner → must return NULL (not 0). + tk.MustExec("truncate table tn") + tk.MustExec("truncate table sn") + tk.MustExec("insert into tn values (null)") + tk.MustExec("insert into sn values (1)") + tk.MustQuery("select tn.a in (select sn.a from sn) as r from tn").Check(testkit.Rows("")) + + // Case 3: both columns NOT NULL → correlate is safe; verify correct results. + tk.MustExec("drop table if exists tnn, snn") + tk.MustExec("create table tnn(a int not null)") + tk.MustExec("create table snn(a int not null, key(a))") + tk.MustExec("insert into tnn values (1), (2), (3)") + tk.MustExec("insert into snn values (1), (2)") + tk.MustQuery("select tnn.a in (select snn.a from snn) as r from tnn order by tnn.a").Check(testkit.Rows("1", "1", "0")) +} + +// TestCorrelateAlternativeChoosesApply verifies that the correlate alternative +// round produces an Apply plan that wins the cost comparison for a non-correlated +// IN subquery when an outer WHERE predicate reduces the estimated row count. +// Without alternative plans, the InnerJoin+Agg rewrite produces IndexJoin+StreamAgg. +// With alternative plans, the correlate round produces Apply+Limit which is cheaper +// (avoids the StreamAgg overhead and uses Limit 1 for early exit on the inner side). +func TestCorrelateAlternativeChoosesApply(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + + tk.MustExec("drop table if exists t1, t2") + tk.MustExec("create table t1 (a int not null, b int, key(a))") + tk.MustExec("create table t2 (a int not null, b int, key(a))") + tk.MustExec("insert into t1 values (1,1),(2,2),(3,3)") + tk.MustExec("insert into t2 values (1,10),(2,20)") + + sql := "select * from t1 where b = 1 and a in (select a from t2)" + + // Without alternative plans: standard InnerJoin+Agg path produces IndexJoin. + tk.MustExec("set tidb_opt_enable_alternative_logical_plans = OFF") + rows := tk.MustQuery("explain format = 'brief' " + sql).Rows() + require.True(t, explainContains(rows, "IndexJoin"), + "without alternative plans, expected IndexJoin in plan:\n%s", joinExplainRows(rows)) + + // With alternative plans: correlate round produces Apply (cheaper than IndexJoin+StreamAgg). + tk.MustExec("set tidb_opt_enable_alternative_logical_plans = ON") + rows = tk.MustQuery("explain format = 'brief' " + sql).Rows() + require.True(t, explainContains(rows, "Apply"), + "with alternative plans, expected Apply in plan:\n%s", joinExplainRows(rows)) + + // Verify correct results in both modes. + tk.MustExec("set tidb_opt_enable_alternative_logical_plans = OFF") + tk.MustQuery(sql).Check(testkit.Rows("1 1")) + tk.MustExec("set tidb_opt_enable_alternative_logical_plans = ON") + tk.MustQuery(sql).Check(testkit.Rows("1 1")) +} + +func TestCorrelate(tt *testing.T) { + testkit.RunTestUnderCascades(tt, func(t *testing.T, tk *testkit.TestKit, cascades, caller string) { + tk.MustExec("use test") + tk.MustExec("drop table if exists t1, t2, t3") + tk.MustExec("create table t1 (a int, b int, key(a))") + tk.MustExec("create table t2 (a int, b int, key(a))") + tk.MustExec("create table t3 (a int, b int, key(a))") + tk.MustExec("insert into t1 values (1,1),(2,2),(3,3)") + tk.MustExec("insert into t2 values (1,10),(2,20)") + tk.MustExec("insert into t3 values (10,1),(20,2)") + + // Enable the correlate rule. + tk.MustExec("set tidb_opt_enable_alternative_logical_plans = ON") + + var input []string + var output []struct { + SQL string + Plan []string + Result []string + } + suite := GetCorrelateSuiteData() + suite.LoadTestCases(t, &input, &output, cascades, caller) + for i, sql := range input { + testdata.OnRecord(func() { + output[i].SQL = sql + output[i].Plan = testdata.ConvertRowsToStrings(tk.MustQuery("explain format = 'brief' " + sql).Rows()) + output[i].Result = testdata.ConvertRowsToStrings(tk.MustQuery(sql).Rows()) + }) + tk.MustQuery("explain format = 'brief' " + sql).Check(testkit.Rows(output[i].Plan...)) + tk.MustQuery(sql).Check(testkit.Rows(output[i].Result...)) + } + }) +} + +// explainContains scans all explain rows for a substring in the operator column. +func explainContains(rows [][]any, substr string) bool { + for _, row := range rows { + if strings.Contains(row[0].(string), substr) { + return true + } + } + return false +} + +// joinExplainRows formats explain rows into a single string for debug output. +func joinExplainRows(rows [][]any) string { + var sb strings.Builder + for _, row := range rows { + sb.WriteString(row[0].(string)) + sb.WriteByte('\n') + } + return sb.String() +} + +// TestCorrelateParallelApply verifies that when the correlate alternative round +// produces an Apply plan and tidb_enable_parallel_apply is ON, the Apply is +// executed with parallel concurrency. This tests the interaction between the +// correlate optimization (converting decorrelated semi-join back to Apply) and +// the parallel apply executor. +func TestCorrelateParallelApply(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + + tk.MustExec("drop table if exists t1, t2") + tk.MustExec("create table t1 (a int not null, b int, key(a))") + tk.MustExec("create table t2 (a int not null, b int, key(a))") + tk.MustExec("insert into t1 values (1,1),(2,2),(3,3),(4,4),(5,5)") + tk.MustExec("insert into t2 values (1,10),(2,20),(3,30)") + + sql := "select * from t1 where b = 1 and a in (select a from t2)" + + // Enable correlate alternative + parallel apply. + tk.MustExec("set tidb_opt_enable_alternative_logical_plans = ON") + tk.MustExec("set tidb_enable_parallel_apply = ON") + tk.MustExec("set tidb_executor_concurrency = 5") + + // Verify the plan contains Apply (correlate alternative won). + rows := tk.MustQuery("explain format = 'brief' " + sql).Rows() + require.True(t, explainContains(rows, "Apply"), + "with correlate alternative + parallel apply, expected Apply in plan:\n%s", joinExplainRows(rows)) + + // Verify EXPLAIN ANALYZE reports Concurrency > 1 for the Apply. + analyzeRows := tk.MustQuery("explain analyze " + sql).Rows() + foundConcurrency := false + for _, row := range analyzeRows { + line := fmt.Sprintf("%v", row) + if strings.Contains(line, "Apply") && strings.Contains(line, "Concurrency:") { + idx := strings.Index(line, "Concurrency:") + if idx >= 0 { + rest := line[idx+len("Concurrency:"):] + var n int + if _, err := fmt.Sscanf(rest, "%d", &n); err == nil && n > 1 { + foundConcurrency = true + } + } + break + } + } + require.True(t, foundConcurrency, + "EXPLAIN ANALYZE must report Concurrency > 1 for Apply when parallel_apply is on") + + // Verify correctness: parallel + correlate must match serial + no correlate. + tk.MustExec("set tidb_enable_parallel_apply = OFF") + tk.MustExec("set tidb_opt_enable_alternative_logical_plans = OFF") + serialRows := tk.MustQuery(sql).Rows() + + tk.MustExec("set tidb_enable_parallel_apply = ON") + tk.MustExec("set tidb_opt_enable_alternative_logical_plans = ON") + parallelRows := tk.MustQuery(sql).Rows() + + require.Equal(t, serialRows, parallelRows, + "correlate alternative + parallel apply must produce the same result as standard path") +} + +// TestCorrelateWithCostFactors verifies that when hash/merge join cost factors +// are increased, the correlate alternative round wins and produces Apply-based +// plans with correlated index access for cases that normally choose HashJoin. +func TestCorrelateWithCostFactors(tt *testing.T) { + testkit.RunTestUnderCascades(tt, func(t *testing.T, tk *testkit.TestKit, cascades, caller string) { + tk.MustExec("use test") + tk.MustExec("drop table if exists t1, t2, t3") + tk.MustExec("create table t1 (a int, b int, key(a))") + tk.MustExec("create table t2 (a int, b int, key(a))") + tk.MustExec("create table t3 (a int, b int, key(a))") + tk.MustExec("insert into t1 values (1,1),(2,2),(3,3)") + tk.MustExec("insert into t2 values (1,10),(2,20)") + tk.MustExec("insert into t3 values (10,1),(20,2)") + + // Enable the correlate rule and penalize hash/merge joins so the + // correlate alternative (Apply with index lookup) wins the cost comparison. + tk.MustExec("set tidb_opt_enable_alternative_logical_plans = ON") + tk.MustExec("set tidb_opt_hash_join_cost_factor = 1000") + tk.MustExec("set tidb_opt_merge_join_cost_factor = 1000") + + var input []string + var output []struct { + SQL string + Plan []string + Result []string + } + suite := GetCorrelateSuiteData() + suite.LoadTestCases(t, &input, &output, cascades, caller) + for i, sql := range input { + testdata.OnRecord(func() { + output[i].SQL = sql + output[i].Plan = testdata.ConvertRowsToStrings(tk.MustQuery("explain format = 'brief' " + sql).Rows()) + output[i].Result = testdata.ConvertRowsToStrings(tk.MustQuery(sql).Rows()) + }) + tk.MustQuery("explain format = 'brief' " + sql).Check(testkit.Rows(output[i].Plan...)) + tk.MustQuery(sql).Check(testkit.Rows(output[i].Result...)) + } + }) +} diff --git a/pkg/planner/core/casetest/rule/testdata/cdc_join_reorder_suite_in.json b/pkg/planner/core/casetest/rule/testdata/cdc_join_reorder_suite_in.json new file mode 100644 index 0000000000000..e503a1c113388 --- /dev/null +++ b/pkg/planner/core/casetest/rule/testdata/cdc_join_reorder_suite_in.json @@ -0,0 +1,259 @@ +[ + { + "name": "TestCDCJoinReorder", + "cases": [ + // ============================================= + // Group 1: Inner join reorder (baseline) + // ============================================= + + // 3-table inner join + "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a ORDER BY t1.a", + // 4-table inner join + "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a JOIN t4 ON t3.a = t4.a ORDER BY t1.a", + + // ============================================= + // Group 2: LEFT JOIN + INNER JOIN + // ============================================= + + // assoc(inner, left) = 1: (t1 INNER t2) LEFT t3 + "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a ORDER BY t1.a, t2.a", + // assoc(left, inner) = 0: (t1 LEFT t2) INNER t3 on t1.a = t3.a + // A conflict rule should be added to prevent incorrect reorder. + "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a JOIN t3 ON t1.a = t3.a ORDER BY t1.a, t3.a", + // leftAsscom(left, inner) = 1: (t1 LEFT t2) INNER t3 on t2.a = t3.a + // leftAsscom allows reorder when the inner join condition references the right side of the left join. + "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a ORDER BY t1.a, t2.a, t3.a", + + // ============================================= + // Group 3: RIGHT JOIN + INNER JOIN + // ============================================= + + // assoc(right, inner) = 1: (t1 RIGHT t2) INNER t3 + "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a ORDER BY t2.a, t3.a", + // assoc(inner, right) = 0: (t1 INNER t2) RIGHT t3 + // A conflict rule prevents incorrect reorder. + "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a RIGHT JOIN t3 ON t2.a = t3.a ORDER BY t3.a", + + // ============================================= + // Group 4: Nested LEFT JOINs + // ============================================= + + // assoc(left, left) = 1: (t1 LEFT t2) LEFT t3 on t2.a = t3.a + "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a ORDER BY t1.a", + // leftAsscom(left, left) = 1: (t1 LEFT t2) LEFT t3 on t1.a = t3.a + "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t1.a = t3.a ORDER BY t1.a", + + // ============================================= + // Group 5: Nested RIGHT JOINs + // ============================================= + + // assoc(right, right) = 1: (t1 RIGHT t2) RIGHT t3 on t2.a = t3.a + "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a RIGHT JOIN t3 ON t2.a = t3.a ORDER BY t3.a", + + // ============================================= + // Group 6: LEFT + RIGHT mixed + // ============================================= + + // assoc(right, left) = 1: (t1 RIGHT t2) LEFT t3 on t2.a = t3.a + "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a ORDER BY t2.a", + // assoc(left, right) = 0: (t1 LEFT t2) RIGHT t3 on t1.a = t3.a + // Conflict rule should prevent incorrect reorder. + "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a RIGHT JOIN t3 ON t1.a = t3.a ORDER BY t3.a", + + // ============================================= + // Group 7: rightAsscom(right, left) = 1 + // ============================================= + + // rightAsscom(right, left) = 1: t1 RIGHT (t2 LEFT t3) + // In SQL: t2 LEFT t3 is a subgroup; t1 RIGHT JOIN that. + // We write it as: t1 RIGHT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t1.a = t3.a + // Parse tree: (t1 RIGHT t2) LEFT t3 + // Use a different structure to test rightAsscom: + // t2 LEFT t3 ON t2.a = t3.a, then t1 RIGHT t2 ON t1.b = t2.b + // This is achieved via: t1 RIGHT JOIN (t2 LEFT JOIN t3 ON t2.a = t3.a) ON t1.a = t2.a + // But MySQL syntax doesn't allow this directly. Use: + "SELECT * FROM t2 LEFT JOIN t3 ON t2.a = t3.a RIGHT JOIN t1 ON t2.a = t1.a ORDER BY t1.a", + + // ============================================= + // Group 8: Complex 4-table mixed outer joins + // ============================================= + + // LEFT + INNER + LEFT: (t1 LEFT t2) INNER t3 LEFT t4 + "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a JOIN t3 ON t1.a = t3.a LEFT JOIN t4 ON t3.a = t4.a ORDER BY t1.a", + // RIGHT + INNER + RIGHT: (t1 RIGHT t2) INNER t3 RIGHT t4 + "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a RIGHT JOIN t4 ON t3.a = t4.a ORDER BY t4.a", + // INNER + LEFT + RIGHT: t1 INNER t2 LEFT t3 RIGHT t4 + "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a RIGHT JOIN t4 ON t3.a = t4.a ORDER BY t4.a", + + // ============================================= + // Group 9: All inner join with more complex conditions + // ============================================= + + // Inner join with multiple conditions + "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a AND t1.b < t2.b JOIN t3 ON t2.a = t3.a ORDER BY t1.a", + // Inner join chain with different join columns + "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.b = t3.b ORDER BY t1.a, t2.a, t3.a", + + // ============================================= + // Group 10: Join-condition orientation and filters + // ============================================= + + // Reversed equality orientation to exercise eq condition alignment. + "SELECT * FROM t1 JOIN t2 ON t2.a = t1.a JOIN t3 ON t3.a = t2.a ORDER BY t1.a", + // Inner join with one-side filter in ON condition. + "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a AND t2.b > 150 JOIN t3 ON t2.a = t3.a ORDER BY t1.a, t2.a", + // Degenerate predicate (single-side reference) + normal edge. + "SELECT * FROM t1 JOIN t2 ON t1.b > 15 JOIN t3 ON t2.a = t3.a WHERE t1.a = 3 ORDER BY t2.a, t3.a", + // Cross-style inner join with join predicate in WHERE. + "SELECT * FROM t1 JOIN t2 JOIN t3 ON t2.a = t3.a WHERE t1.a = t2.a ORDER BY t1.a", + + // ============================================= + // Group 11: Reorder barriers and fallback paths + // ============================================= + + // Null-safe equality should stop join-group expansion. + "SELECT * FROM t1 JOIN t2 ON t1.a <=> t2.a JOIN t3 ON t2.a = t3.a ORDER BY t1.a", + // STRAIGHT_JOIN should preserve explicit order. + "SELECT * FROM t1 STRAIGHT_JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a ORDER BY t1.a", + // Non-equi LEFT JOIN should not be reordered as non-inner edge. + "SELECT * FROM t1 LEFT JOIN t2 ON t1.a < t2.a JOIN t3 ON t1.a = t3.a ORDER BY t1.a, t2.a, t3.a", + // Non-equi RIGHT JOIN should not be reordered as non-inner edge. + "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a < t2.a JOIN t3 ON t2.a = t3.a ORDER BY t2.a, t3.a", + + // ============================================= + // Group 12: Parenthesized/derived join groups + // ============================================= + + // Explicit parenthesized mixed joins. + "SELECT * FROM (t1 LEFT JOIN t2 ON t1.a = t2.a) JOIN (t3 JOIN t4 ON t3.a = t4.a) ON t1.a = t3.a ORDER BY t1.a, t3.a", + // Right join over an explicit sub-join. + "SELECT * FROM t1 RIGHT JOIN (t2 LEFT JOIN t3 ON t2.a = t3.a) ON t1.a = t2.a ORDER BY t2.a, t1.a", + // Derived-table leafs inside join reorder. + "SELECT * FROM (SELECT a, b FROM t1 WHERE a <= 3) x JOIN (SELECT a, b FROM t2 WHERE a <= 2) y ON x.a = y.a JOIN t3 ON y.a = t3.a ORDER BY x.a", + // Mixed outer chain with one-side outer condition. + "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a AND t2.b > 150 LEFT JOIN t3 ON t1.a = t3.a JOIN t4 ON t3.a = t4.a ORDER BY t1.a, t4.a", + + // ============================================= + // Group 13: 5-table joins + // ============================================= + + // 5-table inner join chain. + "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a JOIN t4 ON t3.a = t4.a JOIN t5 ON t4.a = t5.a ORDER BY t1.a", + // 5-table mixed: INNER + LEFT + INNER + RIGHT. + "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a JOIN t4 ON t1.a = t4.a RIGHT JOIN t5 ON t4.a = t5.a ORDER BY t5.a", + // 5-table all LEFT JOINs. + "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a LEFT JOIN t4 ON t3.a = t4.a LEFT JOIN t5 ON t4.a = t5.a ORDER BY t1.a", + + // ============================================= + // Group 14: Deep outer join chains (4-table) + // ============================================= + + // 4 consecutive LEFT JOINs: assoc(left,left) exercised at each level. + "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a LEFT JOIN t4 ON t3.a = t4.a ORDER BY t1.a", + // 4 consecutive RIGHT JOINs: assoc(right,right) exercised at each level. + "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a RIGHT JOIN t3 ON t2.a = t3.a RIGHT JOIN t4 ON t3.a = t4.a ORDER BY t4.a", + + // ============================================= + // Group 15: Alternating join type patterns + // ============================================= + + // LEFT-RIGHT-LEFT alternating: conflict rules from mixed joins interact. + "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a RIGHT JOIN t3 ON t2.a = t3.a LEFT JOIN t4 ON t3.a = t4.a ORDER BY t3.a", + // RIGHT-LEFT-RIGHT alternating: another direction of mixed chain. + "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a RIGHT JOIN t4 ON t3.a = t4.a ORDER BY t4.a", + + // ============================================= + // Group 16: WHERE clause interaction with outer joins + // ============================================= + + // WHERE filter on preserved side of 3-table LEFT JOIN chain. + "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a WHERE t1.b > 10 ORDER BY t1.a", + // WHERE IS NULL filter: preserves outer join semantics (anti-join pattern). + "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t1.a = t3.a WHERE t2.a IS NULL ORDER BY t1.a", + // WHERE on null-extended side may convert LEFT to INNER before reorder. + "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a JOIN t3 ON t1.a = t3.a WHERE t2.b > 100 ORDER BY t1.a", + + // ============================================= + // Group 17: Self-joins + // ============================================= + + // Self inner join: same table joined with itself. + "SELECT * FROM t1 x JOIN t1 y ON x.a = y.b ORDER BY x.a, y.a", + // Self left join + another table: CD-C must track distinct vertex IDs. + "SELECT * FROM t1 x LEFT JOIN t1 y ON x.a = y.b JOIN t2 ON x.a = t2.a ORDER BY x.a, t2.a", + + // ============================================= + // Group 18: Compound ON conditions for non-inner edges + // ============================================= + + // LEFT JOIN with multiple ON conditions + INNER. + "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a AND t1.b < t2.b JOIN t3 ON t1.a = t3.a ORDER BY t1.a, t3.a", + // RIGHT JOIN with multiple ON conditions + INNER. + "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a AND t1.b > t2.b JOIN t3 ON t2.a = t3.a ORDER BY t2.a, t3.a", + + // ============================================= + // Group 19: leftAsscom/rightAsscom = 0 specific cases + // ============================================= + + // leftAsscom(right, left) = 0: (t1 RIGHT t2) LEFT t3 ON t1.a = t3.a. + // The LEFT join references the inner side of the RIGHT join. + "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t1.a = t3.a ORDER BY t2.a", + // leftAsscom(right, inner) = 0: (t1 RIGHT t2) INNER t3 ON t1.a = t3.a. + // The INNER join references the inner side of the RIGHT join. + "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a JOIN t3 ON t1.a = t3.a ORDER BY t2.a, t3.a", + // rightAsscom(left, inner) = 0: t1 LEFT (t2 INNER t3). + // Achieved via t2 JOIN t3 ON t2.a = t3.a LEFT JOIN t1 ON t1.a = t2.a, then reversed. + "SELECT * FROM t2 JOIN t3 ON t2.a = t3.a LEFT JOIN t1 ON t1.a = t3.a ORDER BY t2.a", + + // ============================================= + // Group 20: Aggregation and LIMIT on top of join reorder + // ============================================= + + // GROUP BY after 3-table mixed join. + "SELECT t1.a, COUNT(*) FROM t1 JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a GROUP BY t1.a ORDER BY t1.a", + // LIMIT after 3-table inner join. + "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a ORDER BY t1.a LIMIT 2", + + // ============================================= + // Group 21: Semi/Anti join as join-group barriers + // ============================================= + + // EXISTS subquery becomes semi join, forms a barrier for join group expansion. + "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a WHERE EXISTS (SELECT 1 FROM t3 WHERE t3.a = t1.a) ORDER BY t1.a", + // NOT EXISTS subquery becomes anti join. + "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE NOT EXISTS (SELECT 1 FROM t3 WHERE t3.a = t1.a) ORDER BY t1.a", + // IN subquery becomes semi join. + "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a WHERE t1.a IN (SELECT a FROM t3) ORDER BY t1.a", + + // ============================================= + // Group 22: Join with OR and complex predicates + // ============================================= + + // Inner join with OR in WHERE. + "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a WHERE t1.b > 10 OR t2.b > 150 ORDER BY t1.a", + // Left join with compound predicate in ON. + "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a AND (t2.b > 100 OR t2.b < 50) JOIN t3 ON t1.a = t3.a ORDER BY t1.a", + + // ============================================= + // Group 23: Cross join columns (join on column b) + // ============================================= + + // Join on column b instead of a. + "SELECT * FROM t1 JOIN t2 ON t1.b = t2.b LEFT JOIN t3 ON t2.b = t3.b ORDER BY t1.a", + // Mixed columns: a for one edge, b for another. + "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.b = t3.b ORDER BY t1.a" + ] + }, + { + "name": "TestJoinReorderPushSelection", + "cases": [ + "explain format = 'plan_tree' select /*+ leading(t1, t2) */ * from t1 inner join t3 on t1.id=t3.id left join t4 on t4.id=t3.id join t2 on t1.id=t2.id where t3.name like 'test3' or t4.name like 'test4'", + "explain format = 'plan_tree' select /*+ leading(t3, t4, t1, t2) */ * from t1 inner join t3 on t1.id=t3.id left join t4 on t4.id=t3.id join t2 on t1.id=t2.id where t3.name like 'test3' or t4.name like 'test4'", + "explain format = 'plan_tree' select /*+ leading(t1@sel_2, t4, t2@sel_2, t3@sel_2) */ * from (select t1.id, t1.name as n1, t2.name as n2, t3.name as n3 from t1 inner join t2 on t1.id=t2.id left join t3 on t2.id=t3.id where t2.name like 'test2' or t3.name like 'test3') sub inner join t4 on sub.id=t4.id", + "explain format = 'plan_tree' select * from t1 where exists (select 1 from t2 inner join t3 on t2.id=t3.id left join t4 on t4.id=t3.id join t5 on t2.id=t5.id where (t3.name like 'test3' or t4.name like 'test4') and t2.id = t1.id)", + "explain format = 'plan_tree' select /*+ leading(t1@sel_2, t4, t2@sel_2, t3@sel_2) */ * from (select t1.id, t1.name as n1, t2.name as n2, t3.name as n3 from t1 inner join t2 on t1.id=t2.id left join t3 on t2.id=t3.id where t2.name like 'test2' or t3.name like 'test3' or rand() < 0.5) sub inner join t4 on sub.id=t4.id", + "explain format = 'plan_tree' select /*+ leading(t1@sel_2, t4, t2@sel_2, t3@sel_2) */ * from (select t1.id, t1.name as n1, t2.name as n2, t3.name as n3 from t1 inner join t2 on t1.id=t2.id left join t3 on t2.id=t3.id where t2.name like 'test2' or t3.name like 'test3' or sleep(0) = 0) sub inner join t4 on sub.id=t4.id", + "explain format = 'plan_tree' select /*+ leading(t1@sel_3, t5, t4@sel_2, t2@sel_3, t3@sel_3) */ * from (select sub1.id, sub1.n1, sub1.n2, sub1.n3, t4.name as n4 from (select t1.id, t1.name as n1, t2.name as n2, t3.name as n3 from t1 inner join t2 on t1.id=t2.id left join t3 on t2.id=t3.id where t2.name like 'test2' or t3.name like 'test3') sub1 inner join t4 on sub1.id=t4.id) sub2 inner join t5 on sub2.id=t5.id" + ] + } +] diff --git a/pkg/planner/core/casetest/rule/testdata/cdc_join_reorder_suite_out.json b/pkg/planner/core/casetest/rule/testdata/cdc_join_reorder_suite_out.json new file mode 100644 index 0000000000000..cff42adc42e39 --- /dev/null +++ b/pkg/planner/core/casetest/rule/testdata/cdc_join_reorder_suite_out.json @@ -0,0 +1,1342 @@ +[ + { + "Name": "TestCDCJoinReorder", + "Cases": [ + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a JOIN t4 ON t3.a = t4.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root inner join, equal:[eq(test.t3.a, test.t4.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t4.a))", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000 1 10000" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a ORDER BY t1.a, t2.a", + "Plan": [ + "Sort root test.t1.a, test.t2.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000", + "2 20 2 200 " + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a JOIN t3 ON t1.a = t3.a ORDER BY t1.a, t3.a", + "Plan": [ + "Sort root test.t1.a, test.t3.a", + "└─HashJoin root inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000", + "3 30 3 3000" + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a ORDER BY t1.a, t2.a, t3.a", + "Plan": [ + "Sort root test.t1.a, test.t2.a, test.t3.a", + "└─HashJoin root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a ORDER BY t2.a, t3.a", + "Plan": [ + "Sort root test.t2.a, test.t3.a", + "└─HashJoin root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root right outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a RIGHT JOIN t3 ON t2.a = t3.a ORDER BY t3.a", + "Plan": [ + "Sort root test.t3.a", + "└─HashJoin root right outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─HashJoin(Build) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000", + " 3 3000", + " 5 5000" + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000", + "2 20 2 200 ", + "3 30 " + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t1.a = t3.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t1.a, test.t3.a)]", + " ├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000", + "2 20 2 200 ", + "3 30 3 3000" + ] + }, + { + "SQL": "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a RIGHT JOIN t3 ON t2.a = t3.a ORDER BY t3.a", + "Plan": [ + "Sort root test.t3.a", + "└─HashJoin root right outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─HashJoin(Build) root right outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000", + " 3 3000", + " 5 5000" + ] + }, + { + "SQL": "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a ORDER BY t2.a", + "Plan": [ + "Sort root test.t2.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─HashJoin(Build) root right outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:TableFullScan", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000", + "2 20 2 200 ", + " 4 400 " + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a RIGHT JOIN t3 ON t1.a = t3.a ORDER BY t3.a", + "Plan": [ + "Sort root test.t3.a", + "└─HashJoin root right outer join, left side:HashJoin, equal:[eq(test.t1.a, test.t3.a)]", + " ├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000", + "3 30 3 3000", + " 5 5000" + ] + }, + { + "SQL": "SELECT * FROM t2 LEFT JOIN t3 ON t2.a = t3.a RIGHT JOIN t1 ON t2.a = t1.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root right outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t1.a)]", + " ├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(test.t2.a, test.t3.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 100 1 1000 1 10", + "2 200 2 20", + " 3 30" + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a JOIN t3 ON t1.a = t3.a LEFT JOIN t4 ON t3.a = t4.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t3.a, test.t4.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t4.a))", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000 1 10000", + "3 30 3 3000 " + ] + }, + { + "SQL": "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a RIGHT JOIN t4 ON t3.a = t4.a ORDER BY t4.a", + "Plan": [ + "Sort root test.t4.a", + "└─HashJoin root right outer join, left side:HashJoin, equal:[eq(test.t3.a, test.t4.a)]", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root right outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000 1 10000", + " 4 40000", + " 6 60000" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a RIGHT JOIN t4 ON t3.a = t4.a ORDER BY t4.a", + "Plan": [ + "Sort root test.t4.a", + "└─HashJoin root right outer join, left side:HashJoin, equal:[eq(test.t3.a, test.t4.a)]", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000 1 10000", + " 4 40000", + " 6 60000" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a AND t1.b < t2.b JOIN t3 ON t2.a = t3.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)], other cond:lt(test.t1.b, test.t2.b)", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.b = t3.b ORDER BY t1.a, t2.a, t3.a", + "Plan": [ + "Sort root test.t1.a, test.t2.a, test.t3.a", + "└─HashJoin root inner join, equal:[eq(test.t2.b, test.t3.b)]", + " ├─HashJoin(Build) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.b))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": null + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t2.a = t1.a JOIN t3 ON t3.a = t2.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a AND t2.b > 150 JOIN t3 ON t2.a = t3.a ORDER BY t1.a, t2.a", + "Plan": [ + "Sort root test.t1.a, test.t2.a", + "└─Projection root test.t1.a, test.t1.b, test.t2.a, test.t2.b, test.t3.a, test.t3.b", + " └─HashJoin root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─HashJoin(Build) root inner join, equal:[eq(test.t2.a, test.t1.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] gt(test.t2.b, 150), not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": null + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.b > 15 JOIN t3 ON t2.a = t3.a WHERE t1.a = 3 ORDER BY t2.a, t3.a", + "Plan": [ + "Sort root test.t2.a, test.t3.a", + "└─HashJoin root CARTESIAN inner join", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] eq(test.t1.a, 3), gt(test.t1.b, 15)", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t2.a))", + " └─TableFullScan cop[tikv] table:t2 keep order:false" + ], + "Result": [ + "3 30 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 JOIN t3 ON t2.a = t3.a WHERE t1.a = t2.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a <=> t2.a JOIN t3 ON t2.a = t3.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─Projection root test.t1.a, test.t1.b, test.t2.a, test.t2.b, test.t3.a, test.t3.b", + " └─HashJoin root inner join, equal:[eq(test.t3.a, test.t2.a)]", + " ├─HashJoin(Build) root inner join, equal:[nulleq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t1 STRAIGHT_JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─Projection root test.t1.a, test.t1.b, test.t2.a, test.t2.b, test.t3.a, test.t3.b", + " └─HashJoin root inner join, equal:[eq(test.t3.a, test.t2.a)]", + " ├─HashJoin(Build) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a < t2.a JOIN t3 ON t1.a = t3.a ORDER BY t1.a, t2.a, t3.a", + "Plan": [ + "Sort root test.t1.a, test.t2.a, test.t3.a", + "└─Projection root test.t1.a, test.t1.b, test.t2.a, test.t2.b, test.t3.a, test.t3.b", + " └─HashJoin root inner join, equal:[eq(test.t3.a, test.t1.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root CARTESIAN left outer join, left side:TableReader, other cond:lt(test.t1.a, test.t2.a)", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 2 200 1 1000", + "1 10 4 400 1 1000", + "3 30 4 400 3 3000" + ] + }, + { + "SQL": "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a < t2.a JOIN t3 ON t2.a = t3.a ORDER BY t2.a, t3.a", + "Plan": [ + "Sort root test.t2.a, test.t3.a", + "└─Projection root test.t1.a, test.t1.b, test.t2.a, test.t2.b, test.t3.a, test.t3.b", + " └─HashJoin root inner join, equal:[eq(test.t3.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root CARTESIAN right outer join, left side:TableReader, other cond:lt(test.t1.a, test.t2.a)", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + " 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM (t1 LEFT JOIN t2 ON t1.a = t2.a) JOIN (t3 JOIN t4 ON t3.a = t4.a) ON t1.a = t3.a ORDER BY t1.a, t3.a", + "Plan": [ + "Sort root test.t1.a, test.t3.a", + "└─HashJoin root inner join, equal:[eq(test.t3.a, test.t4.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t4.a))", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000 1 10000" + ] + }, + { + "SQL": "SELECT * FROM t1 RIGHT JOIN (t2 LEFT JOIN t3 ON t2.a = t3.a) ON t1.a = t2.a ORDER BY t2.a, t1.a", + "Plan": [ + "Sort root test.t2.a, test.t1.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─HashJoin(Build) root right outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:TableFullScan", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000", + "2 20 2 200 ", + " 4 400 " + ] + }, + { + "SQL": "SELECT * FROM (SELECT a, b FROM t1 WHERE a <= 3) x JOIN (SELECT a, b FROM t2 WHERE a <= 2) y ON x.a = y.a JOIN t3 ON y.a = t3.a ORDER BY x.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─HashJoin(Build) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] le(test.t2.a, 2), le(test.t2.a, 3), not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] le(test.t1.a, 2), le(test.t1.a, 3), not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a AND t2.b > 150 LEFT JOIN t3 ON t1.a = t3.a JOIN t4 ON t3.a = t4.a ORDER BY t1.a, t4.a", + "Plan": [ + "Sort root test.t1.a, test.t4.a", + "└─HashJoin root inner join, equal:[eq(test.t3.a, test.t4.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t4.a))", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] gt(test.t2.b, 150), not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 1000 1 10000" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a JOIN t4 ON t3.a = t4.a JOIN t5 ON t4.a = t5.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root inner join, equal:[eq(test.t4.a, test.t5.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t5.a))", + " │ └─TableFullScan cop[tikv] table:t5 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t3.a, test.t4.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t4.a))", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": null + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a JOIN t4 ON t1.a = t4.a RIGHT JOIN t5 ON t4.a = t5.a ORDER BY t5.a", + "Plan": [ + "Sort root test.t5.a", + "└─HashJoin root right outer join, left side:HashJoin, equal:[eq(test.t4.a, test.t5.a)]", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t5 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t4.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t4.a))", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root left outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + " 2 20000", + " 5 50000", + " 7 70000" + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a LEFT JOIN t4 ON t3.a = t4.a LEFT JOIN t5 ON t4.a = t5.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t4.a, test.t5.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t5.a))", + " │ └─TableFullScan cop[tikv] table:t5 keep order:false", + " └─HashJoin(Probe) root left outer join, left side:HashJoin, equal:[eq(test.t3.a, test.t4.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t4.a))", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root left outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000 1 10000 ", + "2 20 2 200 ", + "3 30 " + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a LEFT JOIN t4 ON t3.a = t4.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t3.a, test.t4.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t4.a))", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root left outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000 1 10000", + "2 20 2 200 ", + "3 30 " + ] + }, + { + "SQL": "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a RIGHT JOIN t3 ON t2.a = t3.a RIGHT JOIN t4 ON t3.a = t4.a ORDER BY t4.a", + "Plan": [ + "Sort root test.t4.a", + "└─HashJoin root right outer join, left side:HashJoin, equal:[eq(test.t3.a, test.t4.a)]", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root right outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root right outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000 1 10000", + " 4 40000", + " 6 60000" + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a RIGHT JOIN t3 ON t2.a = t3.a LEFT JOIN t4 ON t3.a = t4.a ORDER BY t3.a", + "Plan": [ + "Sort root test.t3.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t3.a, test.t4.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t4.a))", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root right outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─HashJoin(Build) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000 1 10000", + " 3 3000 ", + " 5 5000 " + ] + }, + { + "SQL": "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a RIGHT JOIN t4 ON t3.a = t4.a ORDER BY t4.a", + "Plan": [ + "Sort root test.t4.a", + "└─HashJoin root right outer join, left side:HashJoin, equal:[eq(test.t3.a, test.t4.a)]", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root right outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000 1 10000", + " 4 40000", + " 6 60000" + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a WHERE t1.b > 10 ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] gt(test.t1.b, 10)", + " │ │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "2 20 2 200 ", + "3 30 " + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t1.a = t3.a WHERE t2.a IS NULL ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root left outer join, left side:Projection, equal:[eq(test.t1.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─Projection(Probe) root test.t1.a, test.t1.b, ->test.t2.a, ->test.t2.b", + " └─HashJoin root anti semi join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "3 30 3 3000" + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a JOIN t3 ON t1.a = t3.a WHERE t2.b > 100 ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─Projection root test.t1.a, test.t1.b, test.t2.a, test.t2.b, test.t3.a, test.t3.b", + " └─HashJoin root inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─HashJoin(Build) root inner join, equal:[eq(test.t2.a, test.t1.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] gt(test.t2.b, 100), not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": null + }, + { + "SQL": "SELECT * FROM t1 x JOIN t1 y ON x.a = y.b ORDER BY x.a, y.a", + "Plan": [ + "Sort root test.t1.a, test.t1.a", + "└─HashJoin root inner join, equal:[eq(test.t1.a, test.t1.b)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.b))", + " │ └─TableFullScan cop[tikv] table:y keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:x keep order:false" + ], + "Result": null + }, + { + "SQL": "SELECT * FROM t1 x LEFT JOIN t1 y ON x.a = y.b JOIN t2 ON x.a = t2.a ORDER BY x.a, t2.a", + "Plan": [ + "Sort root test.t1.a, test.t2.a", + "└─HashJoin root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─HashJoin(Probe) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t1.b)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.b))", + " │ └─TableFullScan cop[tikv] table:y keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:x keep order:false" + ], + "Result": [ + "1 10 1 100", + "2 20 2 200" + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a AND t1.b < t2.b JOIN t3 ON t1.a = t3.a ORDER BY t1.a, t3.a", + "Plan": [ + "Sort root test.t1.a, test.t3.a", + "└─HashJoin root inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)], other cond:lt(test.t1.b, test.t2.b)", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000", + "3 30 3 3000" + ] + }, + { + "SQL": "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a AND t1.b > t2.b JOIN t3 ON t2.a = t3.a ORDER BY t2.a, t3.a", + "Plan": [ + "Sort root test.t2.a, test.t3.a", + "└─HashJoin root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─HashJoin(Build) root right outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)], other cond:gt(test.t1.b, test.t2.b)", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + " 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t1.a = t3.a ORDER BY t2.a", + "Plan": [ + "Sort root test.t2.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t1.a, test.t3.a)]", + " ├─HashJoin(Build) root right outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:TableFullScan", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000", + "2 20 2 200 ", + " 4 400 " + ] + }, + { + "SQL": "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a JOIN t3 ON t1.a = t3.a ORDER BY t2.a, t3.a", + "Plan": [ + "Sort root test.t2.a, test.t3.a", + "└─HashJoin root inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t2 JOIN t3 ON t2.a = t3.a LEFT JOIN t1 ON t1.a = t3.a ORDER BY t2.a", + "Plan": [ + "Sort root test.t2.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t3.a, test.t1.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t2.a))", + " └─TableFullScan cop[tikv] table:t2 keep order:false" + ], + "Result": [ + "1 100 1 1000 1 10" + ] + }, + { + "SQL": "SELECT t1.a, COUNT(*) FROM t1 JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a GROUP BY t1.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─Projection root test.t1.a, Column", + " └─HashAgg root group by:test.t1.a, funcs:count(1)->Column, funcs:firstrow(test.t1.a)->test.t1.a", + " └─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 1", + "2 1" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a ORDER BY t1.a LIMIT 2", + "Plan": [ + "TopN root test.t1.a, offset:0, count:2", + "└─HashJoin root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a WHERE EXISTS (SELECT 1 FROM t3 WHERE t3.a = t1.a) ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root semi join, left side:HashJoin, equal:[eq(test.t1.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100" + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE NOT EXISTS (SELECT 1 FROM t3 WHERE t3.a = t1.a) ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root anti semi join, left side:HashJoin, equal:[eq(test.t1.a, test.t3.a)]", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "2 20 2 200" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a WHERE t1.a IN (SELECT a FROM t3) ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─HashAgg(Build) root group by:test.t3.a, funcs:firstrow(test.t3.a)->test.t3.a", + " │ └─TableReader root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a WHERE t1.b > 10 OR t2.b > 150 ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)], other cond:or(gt(test.t1.b, 10), gt(test.t2.b, 150))", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": null + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a AND (t2.b > 100 OR t2.b < 50) JOIN t3 ON t1.a = t3.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a)), or(gt(test.t2.b, 100), lt(test.t2.b, 50))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 1000", + "3 30 3 3000" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.b = t2.b LEFT JOIN t3 ON t2.b = t3.b ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t2.b, test.t3.b)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.b))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.b, test.t2.b)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.b))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.b))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": null + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.b = t3.b ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t2.b, test.t3.b)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.b))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 ", + "2 20 2 200 " + ] + } + ] + }, + { + "Name": "TestJoinReorderPushSelection", + "Cases": [ + { + "SQL": "explain format = 'plan_tree' select /*+ leading(t1, t2) */ * from t1 inner join t3 on t1.id=t3.id left join t4 on t4.id=t3.id join t2 on t1.id=t2.id where t3.name like 'test3' or t4.name like 'test4'", + "Plan": [ + "Projection root test.t1.id, test.t1.name, test.t3.id, test.t3.name, test.t4.id, test.t4.name, test.t2.id, test.t2.name", + "└─Selection root or(like(test.t3.name, \"test3\", 92), like(test.t4.name, \"test4\", 92))", + " └─MergeJoin root left outer join, left side:MergeJoin, left key:test.t3.id, right key:test.t4.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t4 keep order:true", + " └─MergeJoin(Probe) root inner join, left key:test.t1.id, right key:test.t3.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t3 keep order:true", + " └─MergeJoin(Probe) root inner join, left key:test.t1.id, right key:test.t2.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t2 keep order:true", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t1 keep order:true" + ] + }, + { + "SQL": "explain format = 'plan_tree' select /*+ leading(t3, t4, t1, t2) */ * from t1 inner join t3 on t1.id=t3.id left join t4 on t4.id=t3.id join t2 on t1.id=t2.id where t3.name like 'test3' or t4.name like 'test4'", + "Plan": [ + "Projection root test.t1.id, test.t1.name, test.t3.id, test.t3.name, test.t4.id, test.t4.name, test.t2.id, test.t2.name", + "└─MergeJoin root inner join, left key:test.t1.id, right key:test.t2.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t2 keep order:true", + " └─MergeJoin(Probe) root inner join, left key:test.t3.id, right key:test.t1.id, other cond:or(like(test.t3.name, \"test3\", 92), like(test.t4.name, \"test4\", 92))", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t1 keep order:true", + " └─MergeJoin(Probe) root left outer join, left side:TableReader, left key:test.t3.id, right key:test.t4.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t4 keep order:true", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t3 keep order:true" + ] + }, + { + "SQL": "explain format = 'plan_tree' select /*+ leading(t1@sel_2, t4, t2@sel_2, t3@sel_2) */ * from (select t1.id, t1.name as n1, t2.name as n2, t3.name as n3 from t1 inner join t2 on t1.id=t2.id left join t3 on t2.id=t3.id where t2.name like 'test2' or t3.name like 'test3') sub inner join t4 on sub.id=t4.id", + "Plan": [ + "Projection root test.t1.id, test.t1.name, test.t2.name, test.t3.name, test.t4.id, test.t4.name", + "└─Selection root or(like(test.t2.name, \"test2\", 92), like(test.t3.name, \"test3\", 92))", + " └─MergeJoin root left outer join, left side:MergeJoin, left key:test.t2.id, right key:test.t3.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t3 keep order:true", + " └─MergeJoin(Probe) root inner join, left key:test.t1.id, right key:test.t2.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t2 keep order:true", + " └─MergeJoin(Probe) root inner join, left key:test.t1.id, right key:test.t4.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t4 keep order:true", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t1 keep order:true" + ] + }, + { + "SQL": "explain format = 'plan_tree' select * from t1 where exists (select 1 from t2 inner join t3 on t2.id=t3.id left join t4 on t4.id=t3.id join t5 on t2.id=t5.id where (t3.name like 'test3' or t4.name like 'test4') and t2.id = t1.id)", + "Plan": [ + "MergeJoin root semi join, left side:TableReader, left key:test.t1.id, right key:test.t2.id", + "├─MergeJoin(Build) root inner join, left key:test.t2.id, right key:test.t5.id", + "│ ├─TableReader(Build) root data:TableFullScan", + "│ │ └─TableFullScan cop[tikv] table:t5 keep order:true", + "│ └─Selection(Probe) root or(like(test.t3.name, \"test3\", 92), like(test.t4.name, \"test4\", 92))", + "│ └─IndexJoin root left outer join, inner:TableReader, left side:MergeJoin, outer key:test.t3.id, inner key:test.t4.id, equal cond:eq(test.t3.id, test.t4.id)", + "│ ├─MergeJoin(Build) root inner join, left key:test.t2.id, right key:test.t3.id", + "│ │ ├─TableReader(Build) root data:TableFullScan", + "│ │ │ └─TableFullScan cop[tikv] table:t3 keep order:true", + "│ │ └─TableReader(Probe) root data:TableFullScan", + "│ │ └─TableFullScan cop[tikv] table:t2 keep order:true", + "│ └─TableReader(Probe) root data:TableRangeScan", + "│ └─TableRangeScan cop[tikv] table:t4 range: decided by [test.t3.id], keep order:false", + "└─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t1 keep order:true" + ] + }, + { + "SQL": "explain format = 'plan_tree' select /*+ leading(t1@sel_2, t4, t2@sel_2, t3@sel_2) */ * from (select t1.id, t1.name as n1, t2.name as n2, t3.name as n3 from t1 inner join t2 on t1.id=t2.id left join t3 on t2.id=t3.id where t2.name like 'test2' or t3.name like 'test3' or rand() < 0.5) sub inner join t4 on sub.id=t4.id", + "Plan": [ + "Projection root test.t1.id, test.t1.name, test.t2.name, test.t3.name, test.t4.id, test.t4.name", + "└─HashJoin root inner join, equal:[eq(test.t4.id, test.t1.id)]", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─Selection(Probe) root or(like(test.t2.name, \"test2\", 92), or(like(test.t3.name, \"test3\", 92), lt(rand(), 0.5)))", + " └─MergeJoin root left outer join, left side:MergeJoin, left key:test.t2.id, right key:test.t3.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t3 keep order:true", + " └─MergeJoin(Probe) root inner join, left key:test.t1.id, right key:test.t2.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t2 keep order:true", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t1 keep order:true" + ] + }, + { + "SQL": "explain format = 'plan_tree' select /*+ leading(t1@sel_2, t4, t2@sel_2, t3@sel_2) */ * from (select t1.id, t1.name as n1, t2.name as n2, t3.name as n3 from t1 inner join t2 on t1.id=t2.id left join t3 on t2.id=t3.id where t2.name like 'test2' or t3.name like 'test3' or sleep(0) = 0) sub inner join t4 on sub.id=t4.id", + "Plan": [ + "Projection root test.t1.id, test.t1.name, test.t2.name, test.t3.name, test.t4.id, test.t4.name", + "└─HashJoin root inner join, equal:[eq(test.t4.id, test.t1.id)]", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─Selection(Probe) root or(like(test.t2.name, \"test2\", 92), or(like(test.t3.name, \"test3\", 92), eq(sleep(0), 0)))", + " └─MergeJoin root left outer join, left side:MergeJoin, left key:test.t2.id, right key:test.t3.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t3 keep order:true", + " └─MergeJoin(Probe) root inner join, left key:test.t1.id, right key:test.t2.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t2 keep order:true", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t1 keep order:true" + ] + }, + { + "SQL": "explain format = 'plan_tree' select /*+ leading(t1@sel_3, t5, t4@sel_2, t2@sel_3, t3@sel_3) */ * from (select sub1.id, sub1.n1, sub1.n2, sub1.n3, t4.name as n4 from (select t1.id, t1.name as n1, t2.name as n2, t3.name as n3 from t1 inner join t2 on t1.id=t2.id left join t3 on t2.id=t3.id where t2.name like 'test2' or t3.name like 'test3') sub1 inner join t4 on sub1.id=t4.id) sub2 inner join t5 on sub2.id=t5.id", + "Plan": [ + "Projection root test.t1.id, test.t1.name, test.t2.name, test.t3.name, test.t4.name, test.t5.id, test.t5.name", + "└─Selection root or(like(test.t2.name, \"test2\", 92), like(test.t3.name, \"test3\", 92))", + " └─MergeJoin root left outer join, left side:MergeJoin, left key:test.t2.id, right key:test.t3.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t3 keep order:true", + " └─MergeJoin(Probe) root inner join, left key:test.t1.id, right key:test.t2.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t2 keep order:true", + " └─MergeJoin(Probe) root inner join, left key:test.t1.id, right key:test.t4.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t4 keep order:true", + " └─MergeJoin(Probe) root inner join, left key:test.t1.id, right key:test.t5.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t5 keep order:true", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t1 keep order:true" + ] + } + ] + } +] diff --git a/pkg/planner/core/casetest/rule/testdata/cdc_join_reorder_suite_xut.json b/pkg/planner/core/casetest/rule/testdata/cdc_join_reorder_suite_xut.json new file mode 100644 index 0000000000000..cff42adc42e39 --- /dev/null +++ b/pkg/planner/core/casetest/rule/testdata/cdc_join_reorder_suite_xut.json @@ -0,0 +1,1342 @@ +[ + { + "Name": "TestCDCJoinReorder", + "Cases": [ + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a JOIN t4 ON t3.a = t4.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root inner join, equal:[eq(test.t3.a, test.t4.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t4.a))", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000 1 10000" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a ORDER BY t1.a, t2.a", + "Plan": [ + "Sort root test.t1.a, test.t2.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000", + "2 20 2 200 " + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a JOIN t3 ON t1.a = t3.a ORDER BY t1.a, t3.a", + "Plan": [ + "Sort root test.t1.a, test.t3.a", + "└─HashJoin root inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000", + "3 30 3 3000" + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a ORDER BY t1.a, t2.a, t3.a", + "Plan": [ + "Sort root test.t1.a, test.t2.a, test.t3.a", + "└─HashJoin root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a ORDER BY t2.a, t3.a", + "Plan": [ + "Sort root test.t2.a, test.t3.a", + "└─HashJoin root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root right outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a RIGHT JOIN t3 ON t2.a = t3.a ORDER BY t3.a", + "Plan": [ + "Sort root test.t3.a", + "└─HashJoin root right outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─HashJoin(Build) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000", + " 3 3000", + " 5 5000" + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000", + "2 20 2 200 ", + "3 30 " + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t1.a = t3.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t1.a, test.t3.a)]", + " ├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000", + "2 20 2 200 ", + "3 30 3 3000" + ] + }, + { + "SQL": "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a RIGHT JOIN t3 ON t2.a = t3.a ORDER BY t3.a", + "Plan": [ + "Sort root test.t3.a", + "└─HashJoin root right outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─HashJoin(Build) root right outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000", + " 3 3000", + " 5 5000" + ] + }, + { + "SQL": "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a ORDER BY t2.a", + "Plan": [ + "Sort root test.t2.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─HashJoin(Build) root right outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:TableFullScan", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000", + "2 20 2 200 ", + " 4 400 " + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a RIGHT JOIN t3 ON t1.a = t3.a ORDER BY t3.a", + "Plan": [ + "Sort root test.t3.a", + "└─HashJoin root right outer join, left side:HashJoin, equal:[eq(test.t1.a, test.t3.a)]", + " ├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000", + "3 30 3 3000", + " 5 5000" + ] + }, + { + "SQL": "SELECT * FROM t2 LEFT JOIN t3 ON t2.a = t3.a RIGHT JOIN t1 ON t2.a = t1.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root right outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t1.a)]", + " ├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(test.t2.a, test.t3.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 100 1 1000 1 10", + "2 200 2 20", + " 3 30" + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a JOIN t3 ON t1.a = t3.a LEFT JOIN t4 ON t3.a = t4.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t3.a, test.t4.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t4.a))", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000 1 10000", + "3 30 3 3000 " + ] + }, + { + "SQL": "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a RIGHT JOIN t4 ON t3.a = t4.a ORDER BY t4.a", + "Plan": [ + "Sort root test.t4.a", + "└─HashJoin root right outer join, left side:HashJoin, equal:[eq(test.t3.a, test.t4.a)]", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root right outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000 1 10000", + " 4 40000", + " 6 60000" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a RIGHT JOIN t4 ON t3.a = t4.a ORDER BY t4.a", + "Plan": [ + "Sort root test.t4.a", + "└─HashJoin root right outer join, left side:HashJoin, equal:[eq(test.t3.a, test.t4.a)]", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000 1 10000", + " 4 40000", + " 6 60000" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a AND t1.b < t2.b JOIN t3 ON t2.a = t3.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)], other cond:lt(test.t1.b, test.t2.b)", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.b = t3.b ORDER BY t1.a, t2.a, t3.a", + "Plan": [ + "Sort root test.t1.a, test.t2.a, test.t3.a", + "└─HashJoin root inner join, equal:[eq(test.t2.b, test.t3.b)]", + " ├─HashJoin(Build) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.b))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": null + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t2.a = t1.a JOIN t3 ON t3.a = t2.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a AND t2.b > 150 JOIN t3 ON t2.a = t3.a ORDER BY t1.a, t2.a", + "Plan": [ + "Sort root test.t1.a, test.t2.a", + "└─Projection root test.t1.a, test.t1.b, test.t2.a, test.t2.b, test.t3.a, test.t3.b", + " └─HashJoin root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─HashJoin(Build) root inner join, equal:[eq(test.t2.a, test.t1.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] gt(test.t2.b, 150), not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": null + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.b > 15 JOIN t3 ON t2.a = t3.a WHERE t1.a = 3 ORDER BY t2.a, t3.a", + "Plan": [ + "Sort root test.t2.a, test.t3.a", + "└─HashJoin root CARTESIAN inner join", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] eq(test.t1.a, 3), gt(test.t1.b, 15)", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t2.a))", + " └─TableFullScan cop[tikv] table:t2 keep order:false" + ], + "Result": [ + "3 30 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 JOIN t3 ON t2.a = t3.a WHERE t1.a = t2.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a <=> t2.a JOIN t3 ON t2.a = t3.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─Projection root test.t1.a, test.t1.b, test.t2.a, test.t2.b, test.t3.a, test.t3.b", + " └─HashJoin root inner join, equal:[eq(test.t3.a, test.t2.a)]", + " ├─HashJoin(Build) root inner join, equal:[nulleq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t1 STRAIGHT_JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─Projection root test.t1.a, test.t1.b, test.t2.a, test.t2.b, test.t3.a, test.t3.b", + " └─HashJoin root inner join, equal:[eq(test.t3.a, test.t2.a)]", + " ├─HashJoin(Build) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a < t2.a JOIN t3 ON t1.a = t3.a ORDER BY t1.a, t2.a, t3.a", + "Plan": [ + "Sort root test.t1.a, test.t2.a, test.t3.a", + "└─Projection root test.t1.a, test.t1.b, test.t2.a, test.t2.b, test.t3.a, test.t3.b", + " └─HashJoin root inner join, equal:[eq(test.t3.a, test.t1.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root CARTESIAN left outer join, left side:TableReader, other cond:lt(test.t1.a, test.t2.a)", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 2 200 1 1000", + "1 10 4 400 1 1000", + "3 30 4 400 3 3000" + ] + }, + { + "SQL": "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a < t2.a JOIN t3 ON t2.a = t3.a ORDER BY t2.a, t3.a", + "Plan": [ + "Sort root test.t2.a, test.t3.a", + "└─Projection root test.t1.a, test.t1.b, test.t2.a, test.t2.b, test.t3.a, test.t3.b", + " └─HashJoin root inner join, equal:[eq(test.t3.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root CARTESIAN right outer join, left side:TableReader, other cond:lt(test.t1.a, test.t2.a)", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + " 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM (t1 LEFT JOIN t2 ON t1.a = t2.a) JOIN (t3 JOIN t4 ON t3.a = t4.a) ON t1.a = t3.a ORDER BY t1.a, t3.a", + "Plan": [ + "Sort root test.t1.a, test.t3.a", + "└─HashJoin root inner join, equal:[eq(test.t3.a, test.t4.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t4.a))", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000 1 10000" + ] + }, + { + "SQL": "SELECT * FROM t1 RIGHT JOIN (t2 LEFT JOIN t3 ON t2.a = t3.a) ON t1.a = t2.a ORDER BY t2.a, t1.a", + "Plan": [ + "Sort root test.t2.a, test.t1.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─HashJoin(Build) root right outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:TableFullScan", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000", + "2 20 2 200 ", + " 4 400 " + ] + }, + { + "SQL": "SELECT * FROM (SELECT a, b FROM t1 WHERE a <= 3) x JOIN (SELECT a, b FROM t2 WHERE a <= 2) y ON x.a = y.a JOIN t3 ON y.a = t3.a ORDER BY x.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─HashJoin(Build) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] le(test.t2.a, 2), le(test.t2.a, 3), not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] le(test.t1.a, 2), le(test.t1.a, 3), not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a AND t2.b > 150 LEFT JOIN t3 ON t1.a = t3.a JOIN t4 ON t3.a = t4.a ORDER BY t1.a, t4.a", + "Plan": [ + "Sort root test.t1.a, test.t4.a", + "└─HashJoin root inner join, equal:[eq(test.t3.a, test.t4.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t4.a))", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] gt(test.t2.b, 150), not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 1000 1 10000" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a JOIN t4 ON t3.a = t4.a JOIN t5 ON t4.a = t5.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root inner join, equal:[eq(test.t4.a, test.t5.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t5.a))", + " │ └─TableFullScan cop[tikv] table:t5 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t3.a, test.t4.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t4.a))", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": null + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a JOIN t4 ON t1.a = t4.a RIGHT JOIN t5 ON t4.a = t5.a ORDER BY t5.a", + "Plan": [ + "Sort root test.t5.a", + "└─HashJoin root right outer join, left side:HashJoin, equal:[eq(test.t4.a, test.t5.a)]", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t5 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t4.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t4.a))", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root left outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + " 2 20000", + " 5 50000", + " 7 70000" + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a LEFT JOIN t4 ON t3.a = t4.a LEFT JOIN t5 ON t4.a = t5.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t4.a, test.t5.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t5.a))", + " │ └─TableFullScan cop[tikv] table:t5 keep order:false", + " └─HashJoin(Probe) root left outer join, left side:HashJoin, equal:[eq(test.t3.a, test.t4.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t4.a))", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root left outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000 1 10000 ", + "2 20 2 200 ", + "3 30 " + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a LEFT JOIN t4 ON t3.a = t4.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t3.a, test.t4.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t4.a))", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root left outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000 1 10000", + "2 20 2 200 ", + "3 30 " + ] + }, + { + "SQL": "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a RIGHT JOIN t3 ON t2.a = t3.a RIGHT JOIN t4 ON t3.a = t4.a ORDER BY t4.a", + "Plan": [ + "Sort root test.t4.a", + "└─HashJoin root right outer join, left side:HashJoin, equal:[eq(test.t3.a, test.t4.a)]", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root right outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root right outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000 1 10000", + " 4 40000", + " 6 60000" + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a RIGHT JOIN t3 ON t2.a = t3.a LEFT JOIN t4 ON t3.a = t4.a ORDER BY t3.a", + "Plan": [ + "Sort root test.t3.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t3.a, test.t4.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t4.a))", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root right outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─HashJoin(Build) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000 1 10000", + " 3 3000 ", + " 5 5000 " + ] + }, + { + "SQL": "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a RIGHT JOIN t4 ON t3.a = t4.a ORDER BY t4.a", + "Plan": [ + "Sort root test.t4.a", + "└─HashJoin root right outer join, left side:HashJoin, equal:[eq(test.t3.a, test.t4.a)]", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root right outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000 1 10000", + " 4 40000", + " 6 60000" + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a WHERE t1.b > 10 ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] gt(test.t1.b, 10)", + " │ │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "2 20 2 200 ", + "3 30 " + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t1.a = t3.a WHERE t2.a IS NULL ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root left outer join, left side:Projection, equal:[eq(test.t1.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─Projection(Probe) root test.t1.a, test.t1.b, ->test.t2.a, ->test.t2.b", + " └─HashJoin root anti semi join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "3 30 3 3000" + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a JOIN t3 ON t1.a = t3.a WHERE t2.b > 100 ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─Projection root test.t1.a, test.t1.b, test.t2.a, test.t2.b, test.t3.a, test.t3.b", + " └─HashJoin root inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─HashJoin(Build) root inner join, equal:[eq(test.t2.a, test.t1.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] gt(test.t2.b, 100), not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": null + }, + { + "SQL": "SELECT * FROM t1 x JOIN t1 y ON x.a = y.b ORDER BY x.a, y.a", + "Plan": [ + "Sort root test.t1.a, test.t1.a", + "└─HashJoin root inner join, equal:[eq(test.t1.a, test.t1.b)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.b))", + " │ └─TableFullScan cop[tikv] table:y keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:x keep order:false" + ], + "Result": null + }, + { + "SQL": "SELECT * FROM t1 x LEFT JOIN t1 y ON x.a = y.b JOIN t2 ON x.a = t2.a ORDER BY x.a, t2.a", + "Plan": [ + "Sort root test.t1.a, test.t2.a", + "└─HashJoin root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─HashJoin(Probe) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t1.b)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.b))", + " │ └─TableFullScan cop[tikv] table:y keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:x keep order:false" + ], + "Result": [ + "1 10 1 100", + "2 20 2 200" + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a AND t1.b < t2.b JOIN t3 ON t1.a = t3.a ORDER BY t1.a, t3.a", + "Plan": [ + "Sort root test.t1.a, test.t3.a", + "└─HashJoin root inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)], other cond:lt(test.t1.b, test.t2.b)", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000", + "3 30 3 3000" + ] + }, + { + "SQL": "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a AND t1.b > t2.b JOIN t3 ON t2.a = t3.a ORDER BY t2.a, t3.a", + "Plan": [ + "Sort root test.t2.a, test.t3.a", + "└─HashJoin root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─HashJoin(Build) root right outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)], other cond:gt(test.t1.b, test.t2.b)", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + " 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t1.a = t3.a ORDER BY t2.a", + "Plan": [ + "Sort root test.t2.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t1.a, test.t3.a)]", + " ├─HashJoin(Build) root right outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:TableFullScan", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000", + "2 20 2 200 ", + " 4 400 " + ] + }, + { + "SQL": "SELECT * FROM t1 RIGHT JOIN t2 ON t1.a = t2.a JOIN t3 ON t1.a = t3.a ORDER BY t2.a, t3.a", + "Plan": [ + "Sort root test.t2.a, test.t3.a", + "└─HashJoin root inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t2 JOIN t3 ON t2.a = t3.a LEFT JOIN t1 ON t1.a = t3.a ORDER BY t2.a", + "Plan": [ + "Sort root test.t2.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t3.a, test.t1.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t2.a))", + " └─TableFullScan cop[tikv] table:t2 keep order:false" + ], + "Result": [ + "1 100 1 1000 1 10" + ] + }, + { + "SQL": "SELECT t1.a, COUNT(*) FROM t1 JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.a = t3.a GROUP BY t1.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─Projection root test.t1.a, Column", + " └─HashAgg root group by:test.t1.a, funcs:count(1)->Column, funcs:firstrow(test.t1.a)->test.t1.a", + " └─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 1", + "2 1" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a ORDER BY t1.a LIMIT 2", + "Plan": [ + "TopN root test.t1.a, offset:0, count:2", + "└─HashJoin root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 1 1000" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a WHERE EXISTS (SELECT 1 FROM t3 WHERE t3.a = t1.a) ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root semi join, left side:HashJoin, equal:[eq(test.t1.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100" + ] + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE NOT EXISTS (SELECT 1 FROM t3 WHERE t3.a = t1.a) ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root anti semi join, left side:HashJoin, equal:[eq(test.t1.a, test.t3.a)]", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "2 20 2 200" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a WHERE t1.a IN (SELECT a FROM t3) ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─HashAgg(Build) root group by:test.t3.a, funcs:firstrow(test.t3.a)->test.t3.a", + " │ └─TableReader root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a JOIN t3 ON t2.a = t3.a WHERE t1.b > 10 OR t2.b > 150 ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root inner join, equal:[eq(test.t2.a, test.t3.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.a))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)], other cond:or(gt(test.t1.b, 10), gt(test.t2.b, 150))", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": null + }, + { + "SQL": "SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a AND (t2.b > 100 OR t2.b < 50) JOIN t3 ON t1.a = t3.a ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " │ ├─TableReader(Build) root data:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.t2.a)), or(gt(test.t2.b, 100), lt(test.t2.b, 50))", + " │ │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t1.a))", + " │ └─TableFullScan cop[tikv] table:t1 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan cop[tikv] table:t3 keep order:false" + ], + "Result": [ + "1 10 1 1000", + "3 30 3 3000" + ] + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.b = t2.b LEFT JOIN t3 ON t2.b = t3.b ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t2.b, test.t3.b)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.b))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.b, test.t2.b)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.b))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.b))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": null + }, + { + "SQL": "SELECT * FROM t1 JOIN t2 ON t1.a = t2.a LEFT JOIN t3 ON t2.b = t3.b ORDER BY t1.a", + "Plan": [ + "Sort root test.t1.a", + "└─HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t2.b, test.t3.b)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t3.b))", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false", + " └─HashJoin(Probe) root inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─TableReader(Build) root data:Selection", + " │ └─Selection cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan cop[tikv] table:t1 keep order:false" + ], + "Result": [ + "1 10 1 100 ", + "2 20 2 200 " + ] + } + ] + }, + { + "Name": "TestJoinReorderPushSelection", + "Cases": [ + { + "SQL": "explain format = 'plan_tree' select /*+ leading(t1, t2) */ * from t1 inner join t3 on t1.id=t3.id left join t4 on t4.id=t3.id join t2 on t1.id=t2.id where t3.name like 'test3' or t4.name like 'test4'", + "Plan": [ + "Projection root test.t1.id, test.t1.name, test.t3.id, test.t3.name, test.t4.id, test.t4.name, test.t2.id, test.t2.name", + "└─Selection root or(like(test.t3.name, \"test3\", 92), like(test.t4.name, \"test4\", 92))", + " └─MergeJoin root left outer join, left side:MergeJoin, left key:test.t3.id, right key:test.t4.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t4 keep order:true", + " └─MergeJoin(Probe) root inner join, left key:test.t1.id, right key:test.t3.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t3 keep order:true", + " └─MergeJoin(Probe) root inner join, left key:test.t1.id, right key:test.t2.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t2 keep order:true", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t1 keep order:true" + ] + }, + { + "SQL": "explain format = 'plan_tree' select /*+ leading(t3, t4, t1, t2) */ * from t1 inner join t3 on t1.id=t3.id left join t4 on t4.id=t3.id join t2 on t1.id=t2.id where t3.name like 'test3' or t4.name like 'test4'", + "Plan": [ + "Projection root test.t1.id, test.t1.name, test.t3.id, test.t3.name, test.t4.id, test.t4.name, test.t2.id, test.t2.name", + "└─MergeJoin root inner join, left key:test.t1.id, right key:test.t2.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t2 keep order:true", + " └─MergeJoin(Probe) root inner join, left key:test.t3.id, right key:test.t1.id, other cond:or(like(test.t3.name, \"test3\", 92), like(test.t4.name, \"test4\", 92))", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t1 keep order:true", + " └─MergeJoin(Probe) root left outer join, left side:TableReader, left key:test.t3.id, right key:test.t4.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t4 keep order:true", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t3 keep order:true" + ] + }, + { + "SQL": "explain format = 'plan_tree' select /*+ leading(t1@sel_2, t4, t2@sel_2, t3@sel_2) */ * from (select t1.id, t1.name as n1, t2.name as n2, t3.name as n3 from t1 inner join t2 on t1.id=t2.id left join t3 on t2.id=t3.id where t2.name like 'test2' or t3.name like 'test3') sub inner join t4 on sub.id=t4.id", + "Plan": [ + "Projection root test.t1.id, test.t1.name, test.t2.name, test.t3.name, test.t4.id, test.t4.name", + "└─Selection root or(like(test.t2.name, \"test2\", 92), like(test.t3.name, \"test3\", 92))", + " └─MergeJoin root left outer join, left side:MergeJoin, left key:test.t2.id, right key:test.t3.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t3 keep order:true", + " └─MergeJoin(Probe) root inner join, left key:test.t1.id, right key:test.t2.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t2 keep order:true", + " └─MergeJoin(Probe) root inner join, left key:test.t1.id, right key:test.t4.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t4 keep order:true", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t1 keep order:true" + ] + }, + { + "SQL": "explain format = 'plan_tree' select * from t1 where exists (select 1 from t2 inner join t3 on t2.id=t3.id left join t4 on t4.id=t3.id join t5 on t2.id=t5.id where (t3.name like 'test3' or t4.name like 'test4') and t2.id = t1.id)", + "Plan": [ + "MergeJoin root semi join, left side:TableReader, left key:test.t1.id, right key:test.t2.id", + "├─MergeJoin(Build) root inner join, left key:test.t2.id, right key:test.t5.id", + "│ ├─TableReader(Build) root data:TableFullScan", + "│ │ └─TableFullScan cop[tikv] table:t5 keep order:true", + "│ └─Selection(Probe) root or(like(test.t3.name, \"test3\", 92), like(test.t4.name, \"test4\", 92))", + "│ └─IndexJoin root left outer join, inner:TableReader, left side:MergeJoin, outer key:test.t3.id, inner key:test.t4.id, equal cond:eq(test.t3.id, test.t4.id)", + "│ ├─MergeJoin(Build) root inner join, left key:test.t2.id, right key:test.t3.id", + "│ │ ├─TableReader(Build) root data:TableFullScan", + "│ │ │ └─TableFullScan cop[tikv] table:t3 keep order:true", + "│ │ └─TableReader(Probe) root data:TableFullScan", + "│ │ └─TableFullScan cop[tikv] table:t2 keep order:true", + "│ └─TableReader(Probe) root data:TableRangeScan", + "│ └─TableRangeScan cop[tikv] table:t4 range: decided by [test.t3.id], keep order:false", + "└─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t1 keep order:true" + ] + }, + { + "SQL": "explain format = 'plan_tree' select /*+ leading(t1@sel_2, t4, t2@sel_2, t3@sel_2) */ * from (select t1.id, t1.name as n1, t2.name as n2, t3.name as n3 from t1 inner join t2 on t1.id=t2.id left join t3 on t2.id=t3.id where t2.name like 'test2' or t3.name like 'test3' or rand() < 0.5) sub inner join t4 on sub.id=t4.id", + "Plan": [ + "Projection root test.t1.id, test.t1.name, test.t2.name, test.t3.name, test.t4.id, test.t4.name", + "└─HashJoin root inner join, equal:[eq(test.t4.id, test.t1.id)]", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─Selection(Probe) root or(like(test.t2.name, \"test2\", 92), or(like(test.t3.name, \"test3\", 92), lt(rand(), 0.5)))", + " └─MergeJoin root left outer join, left side:MergeJoin, left key:test.t2.id, right key:test.t3.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t3 keep order:true", + " └─MergeJoin(Probe) root inner join, left key:test.t1.id, right key:test.t2.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t2 keep order:true", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t1 keep order:true" + ] + }, + { + "SQL": "explain format = 'plan_tree' select /*+ leading(t1@sel_2, t4, t2@sel_2, t3@sel_2) */ * from (select t1.id, t1.name as n1, t2.name as n2, t3.name as n3 from t1 inner join t2 on t1.id=t2.id left join t3 on t2.id=t3.id where t2.name like 'test2' or t3.name like 'test3' or sleep(0) = 0) sub inner join t4 on sub.id=t4.id", + "Plan": [ + "Projection root test.t1.id, test.t1.name, test.t2.name, test.t3.name, test.t4.id, test.t4.name", + "└─HashJoin root inner join, equal:[eq(test.t4.id, test.t1.id)]", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t4 keep order:false", + " └─Selection(Probe) root or(like(test.t2.name, \"test2\", 92), or(like(test.t3.name, \"test3\", 92), eq(sleep(0), 0)))", + " └─MergeJoin root left outer join, left side:MergeJoin, left key:test.t2.id, right key:test.t3.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t3 keep order:true", + " └─MergeJoin(Probe) root inner join, left key:test.t1.id, right key:test.t2.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t2 keep order:true", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t1 keep order:true" + ] + }, + { + "SQL": "explain format = 'plan_tree' select /*+ leading(t1@sel_3, t5, t4@sel_2, t2@sel_3, t3@sel_3) */ * from (select sub1.id, sub1.n1, sub1.n2, sub1.n3, t4.name as n4 from (select t1.id, t1.name as n1, t2.name as n2, t3.name as n3 from t1 inner join t2 on t1.id=t2.id left join t3 on t2.id=t3.id where t2.name like 'test2' or t3.name like 'test3') sub1 inner join t4 on sub1.id=t4.id) sub2 inner join t5 on sub2.id=t5.id", + "Plan": [ + "Projection root test.t1.id, test.t1.name, test.t2.name, test.t3.name, test.t4.name, test.t5.id, test.t5.name", + "└─Selection root or(like(test.t2.name, \"test2\", 92), like(test.t3.name, \"test3\", 92))", + " └─MergeJoin root left outer join, left side:MergeJoin, left key:test.t2.id, right key:test.t3.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t3 keep order:true", + " └─MergeJoin(Probe) root inner join, left key:test.t1.id, right key:test.t2.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t2 keep order:true", + " └─MergeJoin(Probe) root inner join, left key:test.t1.id, right key:test.t4.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t4 keep order:true", + " └─MergeJoin(Probe) root inner join, left key:test.t1.id, right key:test.t5.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t5 keep order:true", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t1 keep order:true" + ] + } + ] + } +] diff --git a/pkg/planner/core/casetest/rule/testdata/correlate_suite_in.json b/pkg/planner/core/casetest/rule/testdata/correlate_suite_in.json new file mode 100644 index 0000000000000..b336f9a8cee93 --- /dev/null +++ b/pkg/planner/core/casetest/rule/testdata/correlate_suite_in.json @@ -0,0 +1,39 @@ +[ + { + "name": "TestCorrelate", + "cases": [ + "select * from t1 where exists (select 1 from t2 where t2.a = t1.a)", + "select * from t1 where not exists (select 1 from t2 where t2.a = t1.a)", + "select * from t1 where a in (select a from t2)", + "select * from t1 where exists (select 1 from t2)", + "select * from t1 where a not in (select a from t2)", + "select * from t1 where exists (select 1 from t2 where t2.a > t1.a)", + "select * from t1 where exists (select 1 from t2 where t2.a = t1.a and t2.b > t1.b)", + "select * from t1 where exists (select /*+ NO_DECORRELATE() */ 1 from t2 where t2.a = t1.a)", + "select * from t1 where a in (select t2.a from t2 inner join t3 on t3.a = t2.b where t3.b > 0)", + "select * from t1 where a in (select a from t2) order by a limit 10", + "select * from t1 where a in (select a from t2 where b > 1)", + "select * from t1 where a in (select a from t2 group by a)", + "select * from t1 where a in (select a from t2 where b > 1 group by a)", + "select * from t1 where a in (select a from t2 limit 10)", + "select * from t1 where a in (select a from t2 order by a limit 10)", + "select * from t1 where b = 1 and a in (select a from t2)", + "select * from t1 where b = 1 and exists (select 1 from t2 where t2.a = t1.a) limit 1", + "select * from t1 where b = 1 and a not in (select a from t2) limit 1", + "select * from t1 where b = 1 and a in (select a from t2 where t2.b > 0) limit 1" + ] + }, + { + "name": "TestCorrelateWithCostFactors", + "cases": [ + "select * from t1 where exists (select 1 from t2 where t2.a = t1.a)", + "select * from t1 where not exists (select 1 from t2 where t2.a = t1.a)", + "select * from t1 where a in (select a from t2)", + "select * from t1 where exists (select 1 from t2 where t2.a > t1.a)", + "select * from t1 where exists (select 1 from t2 where t2.a = t1.a and t2.b > t1.b)", + "select * from t1 where a in (select a from t2) order by a limit 10", + "select * from t1 where a in (select a from t2 where b > 1)", + "select * from t1 where a in (select a from t2 order by a limit 10)" + ] + } +] diff --git a/pkg/planner/core/casetest/rule/testdata/correlate_suite_out.json b/pkg/planner/core/casetest/rule/testdata/correlate_suite_out.json new file mode 100644 index 0000000000000..116b759e4e491 --- /dev/null +++ b/pkg/planner/core/casetest/rule/testdata/correlate_suite_out.json @@ -0,0 +1,466 @@ +[ + { + "Name": "TestCorrelate", + "Cases": [ + { + "SQL": "select * from t1 where exists (select 1 from t2 where t2.a = t1.a)", + "Plan": [ + "HashJoin 7992.00 root semi join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + "├─IndexReader(Build) 9990.00 root index:IndexFullScan", + "│ └─IndexFullScan 9990.00 cop[tikv] table:t2, index:a(a) keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where not exists (select 1 from t2 where t2.a = t1.a)", + "Plan": [ + "HashJoin 8000.00 root anti semi join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + "├─IndexReader(Build) 10000.00 root index:IndexFullScan", + "│ └─IndexFullScan 10000.00 cop[tikv] table:t2, index:a(a) keep order:false, stats:pseudo", + "└─TableReader(Probe) 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "3 3" + ] + }, + { + "SQL": "select * from t1 where a in (select a from t2)", + "Plan": [ + "HashJoin 9990.00 root inner join, equal:[eq(test.t1.a, test.t2.a)]", + "├─StreamAgg(Build) 7992.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─IndexReader 7992.00 root index:StreamAgg", + "│ └─StreamAgg 7992.00 cop[tikv] group by:test.t2.a, ", + "│ └─IndexFullScan 9990.00 cop[tikv] table:t2, index:a(a) keep order:true, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where exists (select 1 from t2)", + "Plan": [ + "TableReader 10000.00 root data:TableFullScan", + "└─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "ScalarSubQuery N/A root Output: ScalarQueryCol#10, ScalarQueryCol#11, ScalarQueryCol#12, ScalarQueryCol#13", + "└─TableReader 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2", + "3 3" + ] + }, + { + "SQL": "select * from t1 where a not in (select a from t2)", + "Plan": [ + "HashJoin 8000.00 root Null-aware anti semi join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + "├─IndexReader(Build) 10000.00 root index:IndexFullScan", + "│ └─IndexFullScan 10000.00 cop[tikv] table:t2, index:a(a) keep order:false, stats:pseudo", + "└─TableReader(Probe) 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "3 3" + ] + }, + { + "SQL": "select * from t1 where exists (select 1 from t2 where t2.a > t1.a)", + "Plan": [ + "HashJoin 7992.00 root CARTESIAN semi join, left side:TableReader, other cond:gt(test.t2.a, test.t1.a)", + "├─IndexReader(Build) 9990.00 root index:IndexFullScan", + "│ └─IndexFullScan 9990.00 cop[tikv] table:t2, index:a(a) keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1" + ] + }, + { + "SQL": "select * from t1 where exists (select 1 from t2 where t2.a = t1.a and t2.b > t1.b)", + "Plan": [ + "HashJoin 7984.01 root semi join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)], other cond:gt(test.t2.b, test.t1.b)", + "├─TableReader(Build) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9980.01 root data:Selection", + " └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where exists (select /*+ NO_DECORRELATE() */ 1 from t2 where t2.a = t1.a)", + "Plan": [ + "Apply 10000.00 root CARTESIAN semi join, left side:TableReader", + "├─TableReader(Build) 10000.00 root data:TableFullScan", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─Limit(Probe) 10000.00 root offset:0, count:1", + " └─IndexReader 10000.00 root index:Limit", + " └─Limit 10000.00 cop[tikv] offset:0, count:1", + " └─IndexRangeScan 10000.00 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where a in (select t2.a from t2 inner join t3 on t3.a = t2.b where t3.b > 0)", + "Plan": [ + "HashJoin 5203.12 root inner join, equal:[eq(test.t1.a, test.t2.a)]", + "├─HashAgg(Build) 4162.50 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─HashJoin 4162.50 root inner join, equal:[eq(test.t3.a, test.t2.b)]", + "│ ├─TableReader(Build) 3330.00 root data:Selection", + "│ │ └─Selection 3330.00 cop[tikv] gt(test.t3.b, 0), not(isnull(test.t3.a))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where a in (select a from t2) order by a limit 10", + "Plan": [ + "Limit 10.00 root offset:0, count:10", + "└─MergeJoin 10.00 root inner join, left key:test.t1.a, right key:test.t2.a", + " ├─StreamAgg(Build) 8.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + " │ └─IndexReader 8.00 root index:StreamAgg", + " │ └─StreamAgg 8.00 cop[tikv] group by:test.t2.a, ", + " │ └─IndexFullScan 10.00 cop[tikv] table:t2, index:a(a) keep order:true, stats:pseudo", + " └─Projection(Probe) 10.00 root test.t1.a, test.t1.b", + " └─IndexLookUp 10.00 root ", + " ├─IndexFullScan(Build) 10.00 cop[tikv] table:t1, index:a(a) keep order:true, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where a in (select a from t2 where b > 1)", + "Plan": [ + "HashJoin 3330.00 root inner join, equal:[eq(test.t2.a, test.t1.a)]", + "├─HashAgg(Build) 2664.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─TableReader 2664.00 root data:HashAgg", + "│ └─HashAgg 2664.00 cop[tikv] group by:test.t2.a, ", + "│ └─Selection 3330.00 cop[tikv] gt(test.t2.b, 1), not(isnull(test.t2.a))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where a in (select a from t2 group by a)", + "Plan": [ + "HashJoin 9990.00 root inner join, equal:[eq(test.t1.a, test.t2.a)]", + "├─StreamAgg(Build) 7992.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─IndexReader 7992.00 root index:StreamAgg", + "│ └─StreamAgg 7992.00 cop[tikv] group by:test.t2.a, ", + "│ └─IndexFullScan 9990.00 cop[tikv] table:t2, index:a(a) keep order:true, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where a in (select a from t2 where b > 1 group by a)", + "Plan": [ + "HashJoin 3330.00 root inner join, equal:[eq(test.t2.a, test.t1.a)]", + "├─HashAgg(Build) 2664.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─TableReader 2664.00 root data:HashAgg", + "│ └─HashAgg 2664.00 cop[tikv] group by:test.t2.a, ", + "│ └─Selection 3330.00 cop[tikv] gt(test.t2.b, 1), not(isnull(test.t2.a))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where a in (select a from t2 limit 10)", + "Plan": [ + "IndexHashJoin 10.00 root inner join, inner:IndexLookUp, outer key:test.t2.a, inner key:test.t1.a, equal cond:eq(test.t2.a, test.t1.a)", + "├─HashAgg(Build) 8.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─Selection 8.00 root not(isnull(test.t2.a))", + "│ └─Limit 10.00 root offset:0, count:10", + "│ └─IndexReader 10.00 root index:Limit", + "│ └─Limit 10.00 cop[tikv] offset:0, count:10", + "│ └─IndexFullScan 10.00 cop[tikv] table:t2, index:a(a) keep order:false, stats:pseudo", + "└─IndexLookUp(Probe) 10.00 root ", + " ├─Selection(Build) 10.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─IndexRangeScan 10.01 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t2.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where a in (select a from t2 order by a limit 10)", + "Plan": [ + "IndexHashJoin 10.00 root inner join, inner:IndexLookUp, outer key:test.t2.a, inner key:test.t1.a, equal cond:eq(test.t2.a, test.t1.a)", + "├─StreamAgg(Build) 8.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─Selection 8.00 root not(isnull(test.t2.a))", + "│ └─Limit 10.00 root offset:0, count:10", + "│ └─IndexReader 10.00 root index:Limit", + "│ └─Limit 10.00 cop[tikv] offset:0, count:10", + "│ └─IndexFullScan 10.00 cop[tikv] table:t2, index:a(a) keep order:true, stats:pseudo", + "└─IndexLookUp(Probe) 10.00 root ", + " ├─Selection(Build) 10.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─IndexRangeScan 10.01 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t2.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where b = 1 and a in (select a from t2)", + "Plan": [ + "IndexJoin 9.99 root inner join, inner:StreamAgg, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + "├─TableReader(Build) 9.99 root data:Selection", + "│ └─Selection 9.99 cop[tikv] eq(test.t1.b, 1), not(isnull(test.t1.a))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─StreamAgg(Probe) 9.99 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + " └─IndexReader 9.99 root index:Selection", + " └─Selection 9.99 cop[tikv] not(isnull(test.t2.a))", + " └─IndexRangeScan 10.00 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:true, stats:pseudo" + ], + "Result": [ + "1 1" + ] + }, + { + "SQL": "select * from t1 where b = 1 and exists (select 1 from t2 where t2.a = t1.a) limit 1", + "Plan": [ + "Limit 1.00 root offset:0, count:1", + "└─IndexHashJoin 1.00 root semi join, inner:IndexReader, left side:TableReader, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + " ├─TableReader(Build) 1.27 root data:Selection", + " │ └─Selection 1.27 cop[tikv] eq(test.t1.b, 1), not(isnull(test.t1.a))", + " │ └─TableFullScan 1271.25 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─IndexReader(Probe) 1.59 root index:Selection", + " └─Selection 1.59 cop[tikv] not(isnull(test.t2.a))", + " └─IndexRangeScan 1.59 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo" + ], + "Result": [ + "1 1" + ] + }, + { + "SQL": "select * from t1 where b = 1 and a not in (select a from t2) limit 1", + "Plan": [ + "Limit 1.00 root offset:0, count:1", + "└─HashJoin 1.00 root Null-aware anti semi join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " ├─IndexReader(Build) 10000.00 root index:IndexFullScan", + " │ └─IndexFullScan 10000.00 cop[tikv] table:t2, index:a(a) keep order:false, stats:pseudo", + " └─TableReader(Probe) 1.25 root data:Selection", + " └─Selection 1.25 cop[tikv] eq(test.t1.b, 1)", + " └─TableFullScan 1250.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": null + }, + { + "SQL": "select * from t1 where b = 1 and a in (select a from t2 where t2.b > 0) limit 1", + "Plan": [ + "Limit 1.00 root offset:0, count:1", + "└─IndexJoin 1.00 root inner join, inner:StreamAgg, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + " ├─TableReader(Build) 1.00 root data:Selection", + " │ └─Selection 1.00 cop[tikv] eq(test.t1.b, 1), not(isnull(test.t1.a))", + " │ └─TableFullScan 1001.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─StreamAgg(Probe) 1.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + " └─Projection 1.00 root test.t2.a, test.t2.b", + " └─IndexLookUp 1.00 root ", + " ├─Selection(Build) 3.00 cop[tikv] not(isnull(test.t2.a))", + " │ └─IndexRangeScan 3.00 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:true, stats:pseudo", + " └─Selection(Probe) 1.00 cop[tikv] gt(test.t2.b, 0)", + " └─TableRowIDScan 3.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1" + ] + } + ] + }, + { + "Name": "TestCorrelateWithCostFactors", + "Cases": [ + { + "SQL": "select * from t1 where exists (select 1 from t2 where t2.a = t1.a)", + "Plan": [ + "IndexHashJoin 7992.00 root semi join, inner:IndexReader, left side:TableReader, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + "├─TableReader(Build) 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─IndexReader(Probe) 12487.50 root index:Selection", + " └─Selection 12487.50 cop[tikv] not(isnull(test.t2.a))", + " └─IndexRangeScan 12500.00 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where not exists (select 1 from t2 where t2.a = t1.a)", + "Plan": [ + "IndexHashJoin 8000.00 root anti semi join, inner:IndexReader, left side:TableReader, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + "├─TableReader(Build) 10000.00 root data:TableFullScan", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─IndexReader(Probe) 12500.00 root index:IndexRangeScan", + " └─IndexRangeScan 12500.00 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo" + ], + "Result": [ + "3 3" + ] + }, + { + "SQL": "select * from t1 where a in (select a from t2)", + "Plan": [ + "IndexHashJoin 9990.00 root inner join, inner:IndexLookUp, outer key:test.t2.a, inner key:test.t1.a, equal cond:eq(test.t2.a, test.t1.a)", + "├─StreamAgg(Build) 7992.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─IndexReader 7992.00 root index:StreamAgg", + "│ └─StreamAgg 7992.00 cop[tikv] group by:test.t2.a, ", + "│ └─IndexFullScan 9990.00 cop[tikv] table:t2, index:a(a) keep order:true, stats:pseudo", + "└─IndexLookUp(Probe) 9990.00 root ", + " ├─Selection(Build) 9990.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─IndexRangeScan 10000.00 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t2.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 9990.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where exists (select 1 from t2 where t2.a > t1.a)", + "Plan": [ + "HashJoin 7992.00 root CARTESIAN semi join, left side:TableReader, other cond:gt(test.t2.a, test.t1.a)", + "├─IndexReader(Build) 9990.00 root index:IndexFullScan", + "│ └─IndexFullScan 9990.00 cop[tikv] table:t2, index:a(a) keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1" + ] + }, + { + "SQL": "select * from t1 where exists (select 1 from t2 where t2.a = t1.a and t2.b > t1.b)", + "Plan": [ + "IndexHashJoin 7984.01 root semi join, inner:IndexLookUp, left side:TableReader, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a), other cond:gt(test.t2.b, test.t1.b)", + "├─TableReader(Build) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─IndexLookUp(Probe) 12475.01 root ", + " ├─Selection(Build) 12487.50 cop[tikv] not(isnull(test.t2.a))", + " │ └─IndexRangeScan 12500.00 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", + " └─Selection(Probe) 12475.01 cop[tikv] not(isnull(test.t2.b))", + " └─TableRowIDScan 12487.50 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where a in (select a from t2) order by a limit 10", + "Plan": [ + "Limit 10.00 root offset:0, count:10", + "└─IndexJoin 10.00 root inner join, inner:StreamAgg, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + " ├─Projection(Build) 10.00 root test.t1.a, test.t1.b", + " │ └─IndexLookUp 10.00 root ", + " │ ├─IndexFullScan(Build) 10.00 cop[tikv] table:t1, index:a(a) keep order:true, stats:pseudo", + " │ └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─StreamAgg(Probe) 10.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + " └─IndexReader 10.00 root index:Selection", + " └─Selection 10.00 cop[tikv] not(isnull(test.t2.a))", + " └─IndexRangeScan 10.01 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:true, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where a in (select a from t2 where b > 1)", + "Plan": [ + "IndexHashJoin 3330.00 root inner join, inner:IndexLookUp, outer key:test.t2.a, inner key:test.t1.a, equal cond:eq(test.t2.a, test.t1.a)", + "├─HashAgg(Build) 2664.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─TableReader 2664.00 root data:HashAgg", + "│ └─HashAgg 2664.00 cop[tikv] group by:test.t2.a, ", + "│ └─Selection 3330.00 cop[tikv] gt(test.t2.b, 1), not(isnull(test.t2.a))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─IndexLookUp(Probe) 3330.00 root ", + " ├─Selection(Build) 3330.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─IndexRangeScan 3333.33 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t2.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 3330.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where a in (select a from t2 order by a limit 10)", + "Plan": [ + "IndexHashJoin 10.00 root inner join, inner:IndexLookUp, outer key:test.t2.a, inner key:test.t1.a, equal cond:eq(test.t2.a, test.t1.a)", + "├─StreamAgg(Build) 8.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─Selection 8.00 root not(isnull(test.t2.a))", + "│ └─Limit 10.00 root offset:0, count:10", + "│ └─IndexReader 10.00 root index:Limit", + "│ └─Limit 10.00 cop[tikv] offset:0, count:10", + "│ └─IndexFullScan 10.00 cop[tikv] table:t2, index:a(a) keep order:true, stats:pseudo", + "└─IndexLookUp(Probe) 10.00 root ", + " ├─Selection(Build) 10.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─IndexRangeScan 10.01 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t2.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + } + ] + } +] diff --git a/pkg/planner/core/casetest/rule/testdata/correlate_suite_xut.json b/pkg/planner/core/casetest/rule/testdata/correlate_suite_xut.json new file mode 100644 index 0000000000000..116b759e4e491 --- /dev/null +++ b/pkg/planner/core/casetest/rule/testdata/correlate_suite_xut.json @@ -0,0 +1,466 @@ +[ + { + "Name": "TestCorrelate", + "Cases": [ + { + "SQL": "select * from t1 where exists (select 1 from t2 where t2.a = t1.a)", + "Plan": [ + "HashJoin 7992.00 root semi join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + "├─IndexReader(Build) 9990.00 root index:IndexFullScan", + "│ └─IndexFullScan 9990.00 cop[tikv] table:t2, index:a(a) keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where not exists (select 1 from t2 where t2.a = t1.a)", + "Plan": [ + "HashJoin 8000.00 root anti semi join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + "├─IndexReader(Build) 10000.00 root index:IndexFullScan", + "│ └─IndexFullScan 10000.00 cop[tikv] table:t2, index:a(a) keep order:false, stats:pseudo", + "└─TableReader(Probe) 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "3 3" + ] + }, + { + "SQL": "select * from t1 where a in (select a from t2)", + "Plan": [ + "HashJoin 9990.00 root inner join, equal:[eq(test.t1.a, test.t2.a)]", + "├─StreamAgg(Build) 7992.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─IndexReader 7992.00 root index:StreamAgg", + "│ └─StreamAgg 7992.00 cop[tikv] group by:test.t2.a, ", + "│ └─IndexFullScan 9990.00 cop[tikv] table:t2, index:a(a) keep order:true, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where exists (select 1 from t2)", + "Plan": [ + "TableReader 10000.00 root data:TableFullScan", + "└─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "ScalarSubQuery N/A root Output: ScalarQueryCol#10, ScalarQueryCol#11, ScalarQueryCol#12, ScalarQueryCol#13", + "└─TableReader 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2", + "3 3" + ] + }, + { + "SQL": "select * from t1 where a not in (select a from t2)", + "Plan": [ + "HashJoin 8000.00 root Null-aware anti semi join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + "├─IndexReader(Build) 10000.00 root index:IndexFullScan", + "│ └─IndexFullScan 10000.00 cop[tikv] table:t2, index:a(a) keep order:false, stats:pseudo", + "└─TableReader(Probe) 10000.00 root data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "3 3" + ] + }, + { + "SQL": "select * from t1 where exists (select 1 from t2 where t2.a > t1.a)", + "Plan": [ + "HashJoin 7992.00 root CARTESIAN semi join, left side:TableReader, other cond:gt(test.t2.a, test.t1.a)", + "├─IndexReader(Build) 9990.00 root index:IndexFullScan", + "│ └─IndexFullScan 9990.00 cop[tikv] table:t2, index:a(a) keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1" + ] + }, + { + "SQL": "select * from t1 where exists (select 1 from t2 where t2.a = t1.a and t2.b > t1.b)", + "Plan": [ + "HashJoin 7984.01 root semi join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)], other cond:gt(test.t2.b, test.t1.b)", + "├─TableReader(Build) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9980.01 root data:Selection", + " └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where exists (select /*+ NO_DECORRELATE() */ 1 from t2 where t2.a = t1.a)", + "Plan": [ + "Apply 10000.00 root CARTESIAN semi join, left side:TableReader", + "├─TableReader(Build) 10000.00 root data:TableFullScan", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─Limit(Probe) 10000.00 root offset:0, count:1", + " └─IndexReader 10000.00 root index:Limit", + " └─Limit 10000.00 cop[tikv] offset:0, count:1", + " └─IndexRangeScan 10000.00 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where a in (select t2.a from t2 inner join t3 on t3.a = t2.b where t3.b > 0)", + "Plan": [ + "HashJoin 5203.12 root inner join, equal:[eq(test.t1.a, test.t2.a)]", + "├─HashAgg(Build) 4162.50 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─HashJoin 4162.50 root inner join, equal:[eq(test.t3.a, test.t2.b)]", + "│ ├─TableReader(Build) 3330.00 root data:Selection", + "│ │ └─Selection 3330.00 cop[tikv] gt(test.t3.b, 0), not(isnull(test.t3.a))", + "│ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "│ └─TableReader(Probe) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t2.a)), not(isnull(test.t2.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where a in (select a from t2) order by a limit 10", + "Plan": [ + "Limit 10.00 root offset:0, count:10", + "└─MergeJoin 10.00 root inner join, left key:test.t1.a, right key:test.t2.a", + " ├─StreamAgg(Build) 8.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + " │ └─IndexReader 8.00 root index:StreamAgg", + " │ └─StreamAgg 8.00 cop[tikv] group by:test.t2.a, ", + " │ └─IndexFullScan 10.00 cop[tikv] table:t2, index:a(a) keep order:true, stats:pseudo", + " └─Projection(Probe) 10.00 root test.t1.a, test.t1.b", + " └─IndexLookUp 10.00 root ", + " ├─IndexFullScan(Build) 10.00 cop[tikv] table:t1, index:a(a) keep order:true, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where a in (select a from t2 where b > 1)", + "Plan": [ + "HashJoin 3330.00 root inner join, equal:[eq(test.t2.a, test.t1.a)]", + "├─HashAgg(Build) 2664.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─TableReader 2664.00 root data:HashAgg", + "│ └─HashAgg 2664.00 cop[tikv] group by:test.t2.a, ", + "│ └─Selection 3330.00 cop[tikv] gt(test.t2.b, 1), not(isnull(test.t2.a))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where a in (select a from t2 group by a)", + "Plan": [ + "HashJoin 9990.00 root inner join, equal:[eq(test.t1.a, test.t2.a)]", + "├─StreamAgg(Build) 7992.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─IndexReader 7992.00 root index:StreamAgg", + "│ └─StreamAgg 7992.00 cop[tikv] group by:test.t2.a, ", + "│ └─IndexFullScan 9990.00 cop[tikv] table:t2, index:a(a) keep order:true, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where a in (select a from t2 where b > 1 group by a)", + "Plan": [ + "HashJoin 3330.00 root inner join, equal:[eq(test.t2.a, test.t1.a)]", + "├─HashAgg(Build) 2664.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─TableReader 2664.00 root data:HashAgg", + "│ └─HashAgg 2664.00 cop[tikv] group by:test.t2.a, ", + "│ └─Selection 3330.00 cop[tikv] gt(test.t2.b, 1), not(isnull(test.t2.a))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where a in (select a from t2 limit 10)", + "Plan": [ + "IndexHashJoin 10.00 root inner join, inner:IndexLookUp, outer key:test.t2.a, inner key:test.t1.a, equal cond:eq(test.t2.a, test.t1.a)", + "├─HashAgg(Build) 8.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─Selection 8.00 root not(isnull(test.t2.a))", + "│ └─Limit 10.00 root offset:0, count:10", + "│ └─IndexReader 10.00 root index:Limit", + "│ └─Limit 10.00 cop[tikv] offset:0, count:10", + "│ └─IndexFullScan 10.00 cop[tikv] table:t2, index:a(a) keep order:false, stats:pseudo", + "└─IndexLookUp(Probe) 10.00 root ", + " ├─Selection(Build) 10.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─IndexRangeScan 10.01 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t2.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where a in (select a from t2 order by a limit 10)", + "Plan": [ + "IndexHashJoin 10.00 root inner join, inner:IndexLookUp, outer key:test.t2.a, inner key:test.t1.a, equal cond:eq(test.t2.a, test.t1.a)", + "├─StreamAgg(Build) 8.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─Selection 8.00 root not(isnull(test.t2.a))", + "│ └─Limit 10.00 root offset:0, count:10", + "│ └─IndexReader 10.00 root index:Limit", + "│ └─Limit 10.00 cop[tikv] offset:0, count:10", + "│ └─IndexFullScan 10.00 cop[tikv] table:t2, index:a(a) keep order:true, stats:pseudo", + "└─IndexLookUp(Probe) 10.00 root ", + " ├─Selection(Build) 10.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─IndexRangeScan 10.01 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t2.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where b = 1 and a in (select a from t2)", + "Plan": [ + "IndexJoin 9.99 root inner join, inner:StreamAgg, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + "├─TableReader(Build) 9.99 root data:Selection", + "│ └─Selection 9.99 cop[tikv] eq(test.t1.b, 1), not(isnull(test.t1.a))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─StreamAgg(Probe) 9.99 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + " └─IndexReader 9.99 root index:Selection", + " └─Selection 9.99 cop[tikv] not(isnull(test.t2.a))", + " └─IndexRangeScan 10.00 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:true, stats:pseudo" + ], + "Result": [ + "1 1" + ] + }, + { + "SQL": "select * from t1 where b = 1 and exists (select 1 from t2 where t2.a = t1.a) limit 1", + "Plan": [ + "Limit 1.00 root offset:0, count:1", + "└─IndexHashJoin 1.00 root semi join, inner:IndexReader, left side:TableReader, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + " ├─TableReader(Build) 1.27 root data:Selection", + " │ └─Selection 1.27 cop[tikv] eq(test.t1.b, 1), not(isnull(test.t1.a))", + " │ └─TableFullScan 1271.25 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─IndexReader(Probe) 1.59 root index:Selection", + " └─Selection 1.59 cop[tikv] not(isnull(test.t2.a))", + " └─IndexRangeScan 1.59 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo" + ], + "Result": [ + "1 1" + ] + }, + { + "SQL": "select * from t1 where b = 1 and a not in (select a from t2) limit 1", + "Plan": [ + "Limit 1.00 root offset:0, count:1", + "└─HashJoin 1.00 root Null-aware anti semi join, left side:TableReader, equal:[eq(test.t1.a, test.t2.a)]", + " ├─IndexReader(Build) 10000.00 root index:IndexFullScan", + " │ └─IndexFullScan 10000.00 cop[tikv] table:t2, index:a(a) keep order:false, stats:pseudo", + " └─TableReader(Probe) 1.25 root data:Selection", + " └─Selection 1.25 cop[tikv] eq(test.t1.b, 1)", + " └─TableFullScan 1250.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": null + }, + { + "SQL": "select * from t1 where b = 1 and a in (select a from t2 where t2.b > 0) limit 1", + "Plan": [ + "Limit 1.00 root offset:0, count:1", + "└─IndexJoin 1.00 root inner join, inner:StreamAgg, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + " ├─TableReader(Build) 1.00 root data:Selection", + " │ └─Selection 1.00 cop[tikv] eq(test.t1.b, 1), not(isnull(test.t1.a))", + " │ └─TableFullScan 1001.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─StreamAgg(Probe) 1.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + " └─Projection 1.00 root test.t2.a, test.t2.b", + " └─IndexLookUp 1.00 root ", + " ├─Selection(Build) 3.00 cop[tikv] not(isnull(test.t2.a))", + " │ └─IndexRangeScan 3.00 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:true, stats:pseudo", + " └─Selection(Probe) 1.00 cop[tikv] gt(test.t2.b, 0)", + " └─TableRowIDScan 3.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1" + ] + } + ] + }, + { + "Name": "TestCorrelateWithCostFactors", + "Cases": [ + { + "SQL": "select * from t1 where exists (select 1 from t2 where t2.a = t1.a)", + "Plan": [ + "IndexHashJoin 7992.00 root semi join, inner:IndexReader, left side:TableReader, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + "├─TableReader(Build) 9990.00 root data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─IndexReader(Probe) 12487.50 root index:Selection", + " └─Selection 12487.50 cop[tikv] not(isnull(test.t2.a))", + " └─IndexRangeScan 12500.00 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where not exists (select 1 from t2 where t2.a = t1.a)", + "Plan": [ + "IndexHashJoin 8000.00 root anti semi join, inner:IndexReader, left side:TableReader, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + "├─TableReader(Build) 10000.00 root data:TableFullScan", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─IndexReader(Probe) 12500.00 root index:IndexRangeScan", + " └─IndexRangeScan 12500.00 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo" + ], + "Result": [ + "3 3" + ] + }, + { + "SQL": "select * from t1 where a in (select a from t2)", + "Plan": [ + "IndexHashJoin 9990.00 root inner join, inner:IndexLookUp, outer key:test.t2.a, inner key:test.t1.a, equal cond:eq(test.t2.a, test.t1.a)", + "├─StreamAgg(Build) 7992.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─IndexReader 7992.00 root index:StreamAgg", + "│ └─StreamAgg 7992.00 cop[tikv] group by:test.t2.a, ", + "│ └─IndexFullScan 9990.00 cop[tikv] table:t2, index:a(a) keep order:true, stats:pseudo", + "└─IndexLookUp(Probe) 9990.00 root ", + " ├─Selection(Build) 9990.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─IndexRangeScan 10000.00 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t2.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 9990.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where exists (select 1 from t2 where t2.a > t1.a)", + "Plan": [ + "HashJoin 7992.00 root CARTESIAN semi join, left side:TableReader, other cond:gt(test.t2.a, test.t1.a)", + "├─IndexReader(Build) 9990.00 root index:IndexFullScan", + "│ └─IndexFullScan 9990.00 cop[tikv] table:t2, index:a(a) keep order:false, stats:pseudo", + "└─TableReader(Probe) 9990.00 root data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1" + ] + }, + { + "SQL": "select * from t1 where exists (select 1 from t2 where t2.a = t1.a and t2.b > t1.b)", + "Plan": [ + "IndexHashJoin 7984.01 root semi join, inner:IndexLookUp, left side:TableReader, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a), other cond:gt(test.t2.b, test.t1.b)", + "├─TableReader(Build) 9980.01 root data:Selection", + "│ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + "└─IndexLookUp(Probe) 12475.01 root ", + " ├─Selection(Build) 12487.50 cop[tikv] not(isnull(test.t2.a))", + " │ └─IndexRangeScan 12500.00 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:false, stats:pseudo", + " └─Selection(Probe) 12475.01 cop[tikv] not(isnull(test.t2.b))", + " └─TableRowIDScan 12487.50 cop[tikv] table:t2 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where a in (select a from t2) order by a limit 10", + "Plan": [ + "Limit 10.00 root offset:0, count:10", + "└─IndexJoin 10.00 root inner join, inner:StreamAgg, outer key:test.t1.a, inner key:test.t2.a, equal cond:eq(test.t1.a, test.t2.a)", + " ├─Projection(Build) 10.00 root test.t1.a, test.t1.b", + " │ └─IndexLookUp 10.00 root ", + " │ ├─IndexFullScan(Build) 10.00 cop[tikv] table:t1, index:a(a) keep order:true, stats:pseudo", + " │ └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─StreamAgg(Probe) 10.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + " └─IndexReader 10.00 root index:Selection", + " └─Selection 10.00 cop[tikv] not(isnull(test.t2.a))", + " └─IndexRangeScan 10.01 cop[tikv] table:t2, index:a(a) range: decided by [eq(test.t2.a, test.t1.a)], keep order:true, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where a in (select a from t2 where b > 1)", + "Plan": [ + "IndexHashJoin 3330.00 root inner join, inner:IndexLookUp, outer key:test.t2.a, inner key:test.t1.a, equal cond:eq(test.t2.a, test.t1.a)", + "├─HashAgg(Build) 2664.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─TableReader 2664.00 root data:HashAgg", + "│ └─HashAgg 2664.00 cop[tikv] group by:test.t2.a, ", + "│ └─Selection 3330.00 cop[tikv] gt(test.t2.b, 1), not(isnull(test.t2.a))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + "└─IndexLookUp(Probe) 3330.00 root ", + " ├─Selection(Build) 3330.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─IndexRangeScan 3333.33 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t2.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 3330.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + }, + { + "SQL": "select * from t1 where a in (select a from t2 order by a limit 10)", + "Plan": [ + "IndexHashJoin 10.00 root inner join, inner:IndexLookUp, outer key:test.t2.a, inner key:test.t1.a, equal cond:eq(test.t2.a, test.t1.a)", + "├─StreamAgg(Build) 8.00 root group by:test.t2.a, funcs:firstrow(test.t2.a)->test.t2.a", + "│ └─Selection 8.00 root not(isnull(test.t2.a))", + "│ └─Limit 10.00 root offset:0, count:10", + "│ └─IndexReader 10.00 root index:Limit", + "│ └─Limit 10.00 cop[tikv] offset:0, count:10", + "│ └─IndexFullScan 10.00 cop[tikv] table:t2, index:a(a) keep order:true, stats:pseudo", + "└─IndexLookUp(Probe) 10.00 root ", + " ├─Selection(Build) 10.00 cop[tikv] not(isnull(test.t1.a))", + " │ └─IndexRangeScan 10.01 cop[tikv] table:t1, index:a(a) range: decided by [eq(test.t1.a, test.t2.a)], keep order:false, stats:pseudo", + " └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + ], + "Result": [ + "1 1", + "2 2" + ] + } + ] + } +] diff --git a/pkg/planner/core/casetest/rule/testdata/join_reorder_suite_out.json b/pkg/planner/core/casetest/rule/testdata/join_reorder_suite_out.json index fde3ae47a9c6b..a0536ea9bce7a 100644 --- a/pkg/planner/core/casetest/rule/testdata/join_reorder_suite_out.json +++ b/pkg/planner/core/casetest/rule/testdata/join_reorder_suite_out.json @@ -239,21 +239,18 @@ { "SQL": "select /*+ leading(t2, t1, t3) */ * from t2 left join (t1 left join t3 on t1.a=t3.a) on t2.b=t1.b;", "Plan": [ - "HashJoin 15609.38 root left outer join, left side:TableReader, equal:[eq(test.t2.b, test.t1.b)]", - "├─TableReader(Build) 10000.00 root partition:all data:TableFullScan", - "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - "└─HashJoin(Probe) 12487.50 root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t3.a)]", + "HashJoin 15609.38 root left outer join, left side:HashJoin, equal:[eq(test.t1.a, test.t3.a)]", + "├─TableReader(Build) 9990.00 root partition:all data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "└─HashJoin(Probe) 12487.50 root left outer join, left side:TableReader, equal:[eq(test.t2.b, test.t1.b)]", " ├─TableReader(Build) 9990.00 root partition:all data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", - " └─TableReader(Probe) 9990.00 root partition:all data:Selection", - " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─TableReader(Probe) 10000.00 root partition:all data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" ], - "Warning": [ - "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid", - "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" - ] + "Warning": null }, { "SQL": "select /*+ leading(t2, t3) */ * from t2 left join (t1 join t3 on t1.a=t3.a join t4 on t3.b = t4.b) on t2.b=t1.b;", @@ -274,18 +271,17 @@ " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Warning": [ - "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid", "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" ] }, { "SQL": "select /*+ leading(t3, t4) */ * from t2 left join (t1 join t3 on t1.a=t3.a join t4 on t3.b = t4.b) on t2.b=t1.b;", "Plan": [ - "HashJoin 19492.21 root left outer join, left side:TableReader, equal:[eq(test.t2.b, test.t1.b)]", - "├─TableReader(Build) 10000.00 root partition:all data:TableFullScan", - "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - "└─Projection(Probe) 15593.77 root test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b", - " └─HashJoin 15593.77 root inner join, equal:[eq(test.t3.a, test.t1.a)]", + "Projection 19492.21 root test.t2.a, test.t2.b, test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b", + "└─HashJoin 19492.21 root left outer join, left side:TableReader, equal:[eq(test.t2.b, test.t1.b)]", + " ├─TableReader(Build) 10000.00 root partition:all data:TableFullScan", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t3.a, test.t1.a)]", " ├─TableReader(Build) 9980.01 root partition:all data:Selection", " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", @@ -303,60 +299,58 @@ "SQL": "select /*+ leading(t3, t4) */ * from t2 left join (t1 join t3 on t1.a=t3.a join t4 on t3.b = t4.b) on t2.b=t1.b join t5 on t2.a = t5.a join t6 on t5.b=t6.b;", "Plan": [ "Projection 30426.12 root test.t2.a, test.t2.b, test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b, test.t5.a, test.t5.b, test.t6.a, test.t6.b", - "└─HashJoin 30426.12 root left outer join, left side:HashJoin, equal:[eq(test.t2.b, test.t1.b)]", - " ├─Projection(Build) 15593.77 root test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b", - " │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t3.a, test.t1.a)]", - " │ ├─TableReader(Build) 9980.01 root partition:all data:Selection", - " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t3.b, test.t4.b)]", - " │ ├─TableReader(Build) 9980.01 root partition:all data:Selection", - " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", - " │ └─TableReader(Probe) 9990.00 root partition:all data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo", - " └─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t5.b, test.t6.b)]", - " ├─TableReader(Build) 9990.00 root partition:all data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t6.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", - " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t5.a, test.t2.a)]", - " ├─TableReader(Build) 9980.01 root partition:all data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t5.a)), not(isnull(test.t5.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t5 keep order:false, stats:pseudo", - " └─TableReader(Probe) 9990.00 root partition:all data:Selection", - " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", - " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + "└─HashJoin 30426.12 root inner join, equal:[eq(test.t5.b, test.t6.b)]", + " ├─TableReader(Build) 9990.00 root partition:all data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t6.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 24340.89 root inner join, equal:[eq(test.t2.a, test.t5.a)]", + " ├─TableReader(Build) 9980.01 root partition:all data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t5.a)), not(isnull(test.t5.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t5 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 19492.21 root left outer join, left side:TableReader, equal:[eq(test.t2.b, test.t1.b)]", + " ├─TableReader(Build) 9990.00 root partition:all data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t3.a, test.t1.a)]", + " ├─TableReader(Build) 9980.01 root partition:all data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t3.b, test.t4.b)]", + " ├─TableReader(Build) 9980.01 root partition:all data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9990.00 root partition:all data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo" ], "Warning": null }, { "SQL": "select /*+ leading(t3, t4) leading(t5, t6) */ * from t2 left join (t1 join t3 on t1.a=t3.a join t4 on t3.b = t4.b) on t2.b=t1.b join t5 on t2.a = t5.a join t6 on t5.b=t6.b;", "Plan": [ - "Projection 30426.12 root test.t2.a, test.t2.b, test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b, test.t5.a, test.t5.b, test.t6.a, test.t6.b", - "└─HashJoin 30426.12 root left outer join, left side:HashJoin, equal:[eq(test.t2.b, test.t1.b)]", - " ├─HashJoin(Build) 15593.77 root inner join, equal:[eq(test.t3.b, test.t4.b)]", - " │ ├─TableReader(Build) 9990.00 root partition:all data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo", - " │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t1.a, test.t3.a)]", - " │ ├─TableReader(Build) 9980.01 root partition:all data:Selection", - " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", - " │ └─TableReader(Probe) 9980.01 root partition:all data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t5.b, test.t6.b)]", + "HashJoin 30426.12 root inner join, equal:[eq(test.t5.b, test.t6.b)]", + "├─TableReader(Build) 9990.00 root partition:all data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t6.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", + "└─HashJoin(Probe) 24340.89 root inner join, equal:[eq(test.t2.a, test.t5.a)]", + " ├─TableReader(Build) 9980.01 root partition:all data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t5.a)), not(isnull(test.t5.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t5 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 19492.21 root left outer join, left side:TableReader, equal:[eq(test.t2.b, test.t1.b)]", " ├─TableReader(Build) 9990.00 root partition:all data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t6.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", - " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t5.a, test.t2.a)]", - " ├─TableReader(Build) 9980.01 root partition:all data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t5.a)), not(isnull(test.t5.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t5 keep order:false, stats:pseudo", - " └─TableReader(Probe) 9990.00 root partition:all data:Selection", - " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", - " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t3.b, test.t4.b)]", + " ├─TableReader(Build) 9990.00 root partition:all data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─TableReader(Build) 9980.01 root partition:all data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9980.01 root partition:all data:Selection", + " └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid" @@ -365,33 +359,31 @@ { "SQL": "select /*+ leading(t5, t6, t3, t4) */ * from t2 left join (t1 join t3 on t1.a=t3.a join t4 on t3.b = t4.b) on t2.b=t1.b join t5 on t2.a = t5.a join t6 on t5.b=t6.b;", "Plan": [ - "Projection 30426.12 root test.t2.a, test.t2.b, test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b, test.t5.a, test.t5.b, test.t6.a, test.t6.b", - "└─HashJoin 30426.12 root left outer join, left side:HashJoin, equal:[eq(test.t2.b, test.t1.b)]", - " ├─HashJoin(Build) 15593.77 root inner join, equal:[eq(test.t3.b, test.t4.b)]", - " │ ├─TableReader(Build) 9990.00 root partition:all data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo", - " │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t1.a, test.t3.a)]", - " │ ├─TableReader(Build) 9980.01 root partition:all data:Selection", - " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", - " │ └─TableReader(Probe) 9980.01 root partition:all data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t5.b, test.t6.b)]", + "HashJoin 30426.12 root inner join, equal:[eq(test.t5.b, test.t6.b)]", + "├─TableReader(Build) 9990.00 root partition:all data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t6.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", + "└─HashJoin(Probe) 24340.89 root inner join, equal:[eq(test.t2.a, test.t5.a)]", + " ├─TableReader(Build) 9980.01 root partition:all data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t5.a)), not(isnull(test.t5.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t5 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 19492.21 root left outer join, left side:TableReader, equal:[eq(test.t2.b, test.t1.b)]", " ├─TableReader(Build) 9990.00 root partition:all data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t6.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", - " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t5.a, test.t2.a)]", - " ├─TableReader(Build) 9980.01 root partition:all data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t5.a)), not(isnull(test.t5.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t5 keep order:false, stats:pseudo", - " └─TableReader(Probe) 9990.00 root partition:all data:Selection", - " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", - " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t3.b, test.t4.b)]", + " ├─TableReader(Build) 9990.00 root partition:all data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─TableReader(Build) 9980.01 root partition:all data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9980.01 root partition:all data:Selection", + " └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Warning": [ - "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid", "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" ] }, @@ -449,25 +441,25 @@ { "SQL": "select /*+ leading(t1, t3) */ * from t4 join t on t4.a=t.a right join t1 on t.a = t1.a join t2 on t1.b = t2.b join t3 on t2.b=t3.b;", "Plan": [ - "HashJoin 24389.65 root right outer join, left side:HashJoin, equal:[eq(test.t.a, test.t1.a)]", - "├─HashJoin(Build) 12487.50 root inner join, equal:[eq(test.t4.a, test.t.a)]", - "│ ├─TableReader(Build) 9990.00 root partition:all data:Selection", - "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", - "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", - "│ └─TableReader(Probe) 9990.00 root partition:all data:Selection", - "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", - "│ └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo", - "└─HashJoin(Probe) 15609.38 root inner join, equal:[eq(test.t2.b, test.t3.b)]", + "HashJoin 24389.65 root inner join, equal:[eq(test.t2.b, test.t3.b)]", + "├─TableReader(Build) 9990.00 root partition:all data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "└─HashJoin(Probe) 19511.72 root inner join, equal:[eq(test.t1.b, test.t2.b)]", " ├─TableReader(Build) 9990.00 root partition:all data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", - " └─HashJoin(Probe) 12487.50 root inner join, equal:[eq(test.t1.b, test.t2.b)]", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 15609.38 root right outer join, left side:HashJoin, equal:[eq(test.t.a, test.t1.a)]", " ├─TableReader(Build) 9990.00 root partition:all data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - " └─TableReader(Probe) 9990.00 root partition:all data:Selection", - " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12487.50 root inner join, equal:[eq(test.t4.a, test.t.a)]", + " ├─TableReader(Build) 9990.00 root partition:all data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + " └─TableReader(Probe) 9990.00 root partition:all data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" @@ -1100,24 +1092,19 @@ "Plan": [ "TableReader 15609.38 root MppVersion: 3, data:ExchangeSender", "└─ExchangeSender 15609.38 mpp[tiflash] ExchangeType: PassThrough", - " └─HashJoin 15609.38 mpp[tiflash] left outer join, left side:ExchangeReceiver, equal:[eq(test.t2.b, test.t1.b)]", - " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", - " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t2.b, collate: binary]", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", - " └─ExchangeReceiver(Probe) 12487.50 mpp[tiflash] ", - " └─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.b, collate: binary]", - " └─HashJoin 12487.50 mpp[tiflash] left outer join, left side:Selection, equal:[eq(test.t1.a, test.t3.a)]", - " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", - " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t3.a))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo", - " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t1.b))", - " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + " └─HashJoin 15609.38 mpp[tiflash] left outer join, left side:HashJoin, equal:[eq(test.t1.a, test.t3.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t3.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12487.50 mpp[tiflash] left outer join, left side:TableFullScan, equal:[eq(test.t2.b, test.t1.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" ], - "Warning": [ - "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid", - "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" - ] + "Warning": null }, { "SQL": "select /*+ leading(t2, t3) */ * from t2 left join (t1 join t3 on t1.a=t3.a join t4 on t3.b = t4.b) on t2.b=t1.b;", @@ -1144,7 +1131,6 @@ " └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo" ], "Warning": [ - "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid", "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" ] }, @@ -1153,13 +1139,13 @@ "Plan": [ "TableReader 19492.21 root MppVersion: 3, data:ExchangeSender", "└─ExchangeSender 19492.21 mpp[tiflash] ExchangeType: PassThrough", - " └─HashJoin 19492.21 mpp[tiflash] left outer join, left side:ExchangeReceiver, equal:[eq(test.t2.b, test.t1.b)]", - " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", - " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t2.b, collate: binary]", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", - " └─ExchangeReceiver(Probe) 15593.77 mpp[tiflash] ", - " └─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.b, collate: binary]", - " └─Projection 15593.77 mpp[tiflash] test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b", + " └─Projection 19492.21 mpp[tiflash] test.t2.a, test.t2.b, test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b", + " └─HashJoin 19492.21 mpp[tiflash] left outer join, left side:ExchangeReceiver, equal:[eq(test.t2.b, test.t1.b)]", + " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", + " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t2.b, collate: binary]", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 15593.77 mpp[tiflash] ", + " └─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.b, collate: binary]", " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t3.a, test.t1.a)]", " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", @@ -1181,36 +1167,35 @@ "TableReader 30426.12 root MppVersion: 3, data:ExchangeSender", "└─ExchangeSender 30426.12 mpp[tiflash] ExchangeType: PassThrough", " └─Projection 30426.12 mpp[tiflash] test.t2.a, test.t2.b, test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b, test.t5.a, test.t5.b, test.t6.a, test.t6.b", - " └─HashJoin 30426.12 mpp[tiflash] left outer join, left side:ExchangeReceiver, equal:[eq(test.t2.b, test.t1.b)]", - " ├─ExchangeReceiver(Build) 15593.77 mpp[tiflash] ", - " │ └─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t2.b, collate: binary]", - " │ └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t5.b, test.t6.b)]", - " │ ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", - " │ │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t6.b))", - " │ │ └─TableFullScan 10000.00 mpp[tiflash] table:t6 keep order:false, stats:pseudo", - " │ └─HashJoin(Probe) 12475.01 mpp[tiflash] inner join, equal:[eq(test.t5.a, test.t2.a)]", - " │ ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", - " │ │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t5.a)), not(isnull(test.t5.b))", - " │ │ └─TableFullScan 10000.00 mpp[tiflash] table:t5 keep order:false, stats:pseudo", - " │ └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t2.a))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", - " └─ExchangeReceiver(Probe) 15593.77 mpp[tiflash] ", - " └─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.b, collate: binary]", - " └─Projection 15593.77 mpp[tiflash] test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b", - " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t3.a, test.t1.a)]", - " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", - " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", - " └─HashJoin(Probe) 12475.01 mpp[tiflash] inner join, equal:[eq(test.t3.b, test.t4.b)]", + " └─HashJoin 30426.12 mpp[tiflash] inner join, equal:[eq(test.t5.b, test.t6.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t6.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t6 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 24340.89 mpp[tiflash] inner join, equal:[eq(test.t2.a, test.t5.a)]", + " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", + " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t5.a)), not(isnull(test.t5.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t5 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 19492.21 mpp[tiflash] left outer join, left side:ExchangeReceiver, equal:[eq(test.t2.b, test.t1.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t2.b, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t2.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 15593.77 mpp[tiflash] ", + " └─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.b, collate: binary]", + " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t3.a, test.t1.a)]", " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo", - " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t4.b))", - " └─TableFullScan 10000.00 mpp[tiflash] table:t4 keep order:false, stats:pseudo" + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12475.01 mpp[tiflash] inner join, equal:[eq(test.t3.b, test.t4.b)]", + " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", + " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t4.b))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t4 keep order:false, stats:pseudo" ], "Warning": null }, @@ -1219,36 +1204,35 @@ "Plan": [ "TableReader 30426.12 root MppVersion: 3, data:ExchangeSender", "└─ExchangeSender 30426.12 mpp[tiflash] ExchangeType: PassThrough", - " └─Projection 30426.12 mpp[tiflash] test.t2.a, test.t2.b, test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b, test.t5.a, test.t5.b, test.t6.a, test.t6.b", - " └─HashJoin 30426.12 mpp[tiflash] left outer join, left side:ExchangeReceiver, equal:[eq(test.t2.b, test.t1.b)]", - " ├─ExchangeReceiver(Build) 15593.77 mpp[tiflash] ", - " │ └─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t2.b, collate: binary]", - " │ └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t5.b, test.t6.b)]", - " │ ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", - " │ │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t6.b))", - " │ │ └─TableFullScan 10000.00 mpp[tiflash] table:t6 keep order:false, stats:pseudo", - " │ └─HashJoin(Probe) 12475.01 mpp[tiflash] inner join, equal:[eq(test.t5.a, test.t2.a)]", - " │ ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", - " │ │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t5.a)), not(isnull(test.t5.b))", - " │ │ └─TableFullScan 10000.00 mpp[tiflash] table:t5 keep order:false, stats:pseudo", - " │ └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t2.a))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", - " └─ExchangeReceiver(Probe) 15593.77 mpp[tiflash] ", - " └─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.b, collate: binary]", - " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t3.b, test.t4.b)]", - " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", - " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t4.b))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t4 keep order:false, stats:pseudo", - " └─HashJoin(Probe) 12475.01 mpp[tiflash] inner join, equal:[eq(test.t1.a, test.t3.a)]", - " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", - " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", - " └─Selection(Probe) 9980.01 mpp[tiflash] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - " └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo" + " └─HashJoin 30426.12 mpp[tiflash] inner join, equal:[eq(test.t5.b, test.t6.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t6.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t6 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 24340.89 mpp[tiflash] inner join, equal:[eq(test.t2.a, test.t5.a)]", + " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", + " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t5.a)), not(isnull(test.t5.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t5 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 19492.21 mpp[tiflash] left outer join, left side:ExchangeReceiver, equal:[eq(test.t2.b, test.t1.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t2.b, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t2.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 15593.77 mpp[tiflash] ", + " └─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.b, collate: binary]", + " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t3.b, test.t4.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t4.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t4 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12475.01 mpp[tiflash] inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", + " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─Selection(Probe) 9980.01 mpp[tiflash] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid" @@ -1259,39 +1243,37 @@ "Plan": [ "TableReader 30426.12 root MppVersion: 3, data:ExchangeSender", "└─ExchangeSender 30426.12 mpp[tiflash] ExchangeType: PassThrough", - " └─Projection 30426.12 mpp[tiflash] test.t2.a, test.t2.b, test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b, test.t5.a, test.t5.b, test.t6.a, test.t6.b", - " └─HashJoin 30426.12 mpp[tiflash] left outer join, left side:ExchangeReceiver, equal:[eq(test.t2.b, test.t1.b)]", - " ├─ExchangeReceiver(Build) 15593.77 mpp[tiflash] ", - " │ └─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t2.b, collate: binary]", - " │ └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t5.b, test.t6.b)]", - " │ ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", - " │ │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t6.b))", - " │ │ └─TableFullScan 10000.00 mpp[tiflash] table:t6 keep order:false, stats:pseudo", - " │ └─HashJoin(Probe) 12475.01 mpp[tiflash] inner join, equal:[eq(test.t5.a, test.t2.a)]", - " │ ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", - " │ │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t5.a)), not(isnull(test.t5.b))", - " │ │ └─TableFullScan 10000.00 mpp[tiflash] table:t5 keep order:false, stats:pseudo", - " │ └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t2.a))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", - " └─ExchangeReceiver(Probe) 15593.77 mpp[tiflash] ", - " └─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.b, collate: binary]", - " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t3.b, test.t4.b)]", - " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", - " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t4.b))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t4 keep order:false, stats:pseudo", - " └─HashJoin(Probe) 12475.01 mpp[tiflash] inner join, equal:[eq(test.t1.a, test.t3.a)]", - " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", - " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", - " └─Selection(Probe) 9980.01 mpp[tiflash] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - " └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo" + " └─HashJoin 30426.12 mpp[tiflash] inner join, equal:[eq(test.t5.b, test.t6.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t6.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t6 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 24340.89 mpp[tiflash] inner join, equal:[eq(test.t2.a, test.t5.a)]", + " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", + " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t5.a)), not(isnull(test.t5.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t5 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 19492.21 mpp[tiflash] left outer join, left side:ExchangeReceiver, equal:[eq(test.t2.b, test.t1.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t2.b, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t2.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 15593.77 mpp[tiflash] ", + " └─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.b, collate: binary]", + " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t3.b, test.t4.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t4.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t4 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12475.01 mpp[tiflash] inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", + " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─Selection(Probe) 9980.01 mpp[tiflash] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo" ], "Warning": [ - "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid", "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" ] }, @@ -1365,30 +1347,30 @@ "Plan": [ "TableReader 24389.65 root MppVersion: 3, data:ExchangeSender", "└─ExchangeSender 24389.65 mpp[tiflash] ExchangeType: PassThrough", - " └─HashJoin 24389.65 mpp[tiflash] right outer join, left side:ExchangeReceiver, equal:[eq(test.t.a, test.t1.a)]", - " ├─ExchangeReceiver(Build) 12487.50 mpp[tiflash] ", - " │ └─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", - " │ └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t4.a, test.t.a)]", - " │ ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", - " │ │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t4.a))", - " │ │ └─TableFullScan 10000.00 mpp[tiflash] table:t4 keep order:false, stats:pseudo", - " │ └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", - " └─ExchangeReceiver(Probe) 15609.38 mpp[tiflash] ", - " └─ExchangeSender 15609.38 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.a, collate: binary]", - " └─HashJoin 15609.38 mpp[tiflash] inner join, equal:[eq(test.t2.b, test.t3.b)]", - " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", - " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t3.b))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo", - " └─HashJoin(Probe) 12487.50 mpp[tiflash] inner join, equal:[eq(test.t1.b, test.t2.b)]", - " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", - " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t1.b))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", - " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t2.b))", - " └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + " └─HashJoin 24389.65 mpp[tiflash] inner join, equal:[eq(test.t2.b, test.t3.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t3.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 19511.72 mpp[tiflash] inner join, equal:[eq(test.t1.b, test.t2.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t2.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 15609.38 mpp[tiflash] right outer join, left side:ExchangeReceiver, equal:[eq(test.t.a, test.t1.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.a, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 12487.50 mpp[tiflash] ", + " └─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t4.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t4.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t4 keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" diff --git a/pkg/planner/core/casetest/rule/testdata/join_reorder_suite_xut.json b/pkg/planner/core/casetest/rule/testdata/join_reorder_suite_xut.json index fde3ae47a9c6b..a0536ea9bce7a 100644 --- a/pkg/planner/core/casetest/rule/testdata/join_reorder_suite_xut.json +++ b/pkg/planner/core/casetest/rule/testdata/join_reorder_suite_xut.json @@ -239,21 +239,18 @@ { "SQL": "select /*+ leading(t2, t1, t3) */ * from t2 left join (t1 left join t3 on t1.a=t3.a) on t2.b=t1.b;", "Plan": [ - "HashJoin 15609.38 root left outer join, left side:TableReader, equal:[eq(test.t2.b, test.t1.b)]", - "├─TableReader(Build) 10000.00 root partition:all data:TableFullScan", - "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - "└─HashJoin(Probe) 12487.50 root left outer join, left side:TableReader, equal:[eq(test.t1.a, test.t3.a)]", + "HashJoin 15609.38 root left outer join, left side:HashJoin, equal:[eq(test.t1.a, test.t3.a)]", + "├─TableReader(Build) 9990.00 root partition:all data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "└─HashJoin(Probe) 12487.50 root left outer join, left side:TableReader, equal:[eq(test.t2.b, test.t1.b)]", " ├─TableReader(Build) 9990.00 root partition:all data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.a))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", - " └─TableReader(Probe) 9990.00 root partition:all data:Selection", - " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─TableReader(Probe) 10000.00 root partition:all data:TableFullScan", + " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" ], - "Warning": [ - "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid", - "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" - ] + "Warning": null }, { "SQL": "select /*+ leading(t2, t3) */ * from t2 left join (t1 join t3 on t1.a=t3.a join t4 on t3.b = t4.b) on t2.b=t1.b;", @@ -274,18 +271,17 @@ " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Warning": [ - "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid", "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" ] }, { "SQL": "select /*+ leading(t3, t4) */ * from t2 left join (t1 join t3 on t1.a=t3.a join t4 on t3.b = t4.b) on t2.b=t1.b;", "Plan": [ - "HashJoin 19492.21 root left outer join, left side:TableReader, equal:[eq(test.t2.b, test.t1.b)]", - "├─TableReader(Build) 10000.00 root partition:all data:TableFullScan", - "│ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - "└─Projection(Probe) 15593.77 root test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b", - " └─HashJoin 15593.77 root inner join, equal:[eq(test.t3.a, test.t1.a)]", + "Projection 19492.21 root test.t2.a, test.t2.b, test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b", + "└─HashJoin 19492.21 root left outer join, left side:TableReader, equal:[eq(test.t2.b, test.t1.b)]", + " ├─TableReader(Build) 10000.00 root partition:all data:TableFullScan", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t3.a, test.t1.a)]", " ├─TableReader(Build) 9980.01 root partition:all data:Selection", " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", @@ -303,60 +299,58 @@ "SQL": "select /*+ leading(t3, t4) */ * from t2 left join (t1 join t3 on t1.a=t3.a join t4 on t3.b = t4.b) on t2.b=t1.b join t5 on t2.a = t5.a join t6 on t5.b=t6.b;", "Plan": [ "Projection 30426.12 root test.t2.a, test.t2.b, test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b, test.t5.a, test.t5.b, test.t6.a, test.t6.b", - "└─HashJoin 30426.12 root left outer join, left side:HashJoin, equal:[eq(test.t2.b, test.t1.b)]", - " ├─Projection(Build) 15593.77 root test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b", - " │ └─HashJoin 15593.77 root inner join, equal:[eq(test.t3.a, test.t1.a)]", - " │ ├─TableReader(Build) 9980.01 root partition:all data:Selection", - " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t3.b, test.t4.b)]", - " │ ├─TableReader(Build) 9980.01 root partition:all data:Selection", - " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", - " │ └─TableReader(Probe) 9990.00 root partition:all data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo", - " └─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t5.b, test.t6.b)]", - " ├─TableReader(Build) 9990.00 root partition:all data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t6.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", - " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t5.a, test.t2.a)]", - " ├─TableReader(Build) 9980.01 root partition:all data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t5.a)), not(isnull(test.t5.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t5 keep order:false, stats:pseudo", - " └─TableReader(Probe) 9990.00 root partition:all data:Selection", - " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", - " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + "└─HashJoin 30426.12 root inner join, equal:[eq(test.t5.b, test.t6.b)]", + " ├─TableReader(Build) 9990.00 root partition:all data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t6.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 24340.89 root inner join, equal:[eq(test.t2.a, test.t5.a)]", + " ├─TableReader(Build) 9980.01 root partition:all data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t5.a)), not(isnull(test.t5.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t5 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 19492.21 root left outer join, left side:TableReader, equal:[eq(test.t2.b, test.t1.b)]", + " ├─TableReader(Build) 9990.00 root partition:all data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t3.a, test.t1.a)]", + " ├─TableReader(Build) 9980.01 root partition:all data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t3.b, test.t4.b)]", + " ├─TableReader(Build) 9980.01 root partition:all data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9990.00 root partition:all data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo" ], "Warning": null }, { "SQL": "select /*+ leading(t3, t4) leading(t5, t6) */ * from t2 left join (t1 join t3 on t1.a=t3.a join t4 on t3.b = t4.b) on t2.b=t1.b join t5 on t2.a = t5.a join t6 on t5.b=t6.b;", "Plan": [ - "Projection 30426.12 root test.t2.a, test.t2.b, test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b, test.t5.a, test.t5.b, test.t6.a, test.t6.b", - "└─HashJoin 30426.12 root left outer join, left side:HashJoin, equal:[eq(test.t2.b, test.t1.b)]", - " ├─HashJoin(Build) 15593.77 root inner join, equal:[eq(test.t3.b, test.t4.b)]", - " │ ├─TableReader(Build) 9990.00 root partition:all data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo", - " │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t1.a, test.t3.a)]", - " │ ├─TableReader(Build) 9980.01 root partition:all data:Selection", - " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", - " │ └─TableReader(Probe) 9980.01 root partition:all data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t5.b, test.t6.b)]", + "HashJoin 30426.12 root inner join, equal:[eq(test.t5.b, test.t6.b)]", + "├─TableReader(Build) 9990.00 root partition:all data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t6.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", + "└─HashJoin(Probe) 24340.89 root inner join, equal:[eq(test.t2.a, test.t5.a)]", + " ├─TableReader(Build) 9980.01 root partition:all data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t5.a)), not(isnull(test.t5.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t5 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 19492.21 root left outer join, left side:TableReader, equal:[eq(test.t2.b, test.t1.b)]", " ├─TableReader(Build) 9990.00 root partition:all data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t6.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", - " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t5.a, test.t2.a)]", - " ├─TableReader(Build) 9980.01 root partition:all data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t5.a)), not(isnull(test.t5.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t5 keep order:false, stats:pseudo", - " └─TableReader(Probe) 9990.00 root partition:all data:Selection", - " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", - " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t3.b, test.t4.b)]", + " ├─TableReader(Build) 9990.00 root partition:all data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─TableReader(Build) 9980.01 root partition:all data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9980.01 root partition:all data:Selection", + " └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid" @@ -365,33 +359,31 @@ { "SQL": "select /*+ leading(t5, t6, t3, t4) */ * from t2 left join (t1 join t3 on t1.a=t3.a join t4 on t3.b = t4.b) on t2.b=t1.b join t5 on t2.a = t5.a join t6 on t5.b=t6.b;", "Plan": [ - "Projection 30426.12 root test.t2.a, test.t2.b, test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b, test.t5.a, test.t5.b, test.t6.a, test.t6.b", - "└─HashJoin 30426.12 root left outer join, left side:HashJoin, equal:[eq(test.t2.b, test.t1.b)]", - " ├─HashJoin(Build) 15593.77 root inner join, equal:[eq(test.t3.b, test.t4.b)]", - " │ ├─TableReader(Build) 9990.00 root partition:all data:Selection", - " │ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo", - " │ └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t1.a, test.t3.a)]", - " │ ├─TableReader(Build) 9980.01 root partition:all data:Selection", - " │ │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - " │ │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", - " │ └─TableReader(Probe) 9980.01 root partition:all data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t5.b, test.t6.b)]", + "HashJoin 30426.12 root inner join, equal:[eq(test.t5.b, test.t6.b)]", + "├─TableReader(Build) 9990.00 root partition:all data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t6.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", + "└─HashJoin(Probe) 24340.89 root inner join, equal:[eq(test.t2.a, test.t5.a)]", + " ├─TableReader(Build) 9980.01 root partition:all data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t5.a)), not(isnull(test.t5.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t5 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 19492.21 root left outer join, left side:TableReader, equal:[eq(test.t2.b, test.t1.b)]", " ├─TableReader(Build) 9990.00 root partition:all data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t6.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t6 keep order:false, stats:pseudo", - " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t5.a, test.t2.a)]", - " ├─TableReader(Build) 9980.01 root partition:all data:Selection", - " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t5.a)), not(isnull(test.t5.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t5 keep order:false, stats:pseudo", - " └─TableReader(Probe) 9990.00 root partition:all data:Selection", - " └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", - " └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo" + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 15593.77 root inner join, equal:[eq(test.t3.b, test.t4.b)]", + " ├─TableReader(Build) 9990.00 root partition:all data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─TableReader(Build) 9980.01 root partition:all data:Selection", + " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + " └─TableReader(Probe) 9980.01 root partition:all data:Selection", + " └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Warning": [ - "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid", "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" ] }, @@ -449,25 +441,25 @@ { "SQL": "select /*+ leading(t1, t3) */ * from t4 join t on t4.a=t.a right join t1 on t.a = t1.a join t2 on t1.b = t2.b join t3 on t2.b=t3.b;", "Plan": [ - "HashJoin 24389.65 root right outer join, left side:HashJoin, equal:[eq(test.t.a, test.t1.a)]", - "├─HashJoin(Build) 12487.50 root inner join, equal:[eq(test.t4.a, test.t.a)]", - "│ ├─TableReader(Build) 9990.00 root partition:all data:Selection", - "│ │ └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", - "│ │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", - "│ └─TableReader(Probe) 9990.00 root partition:all data:Selection", - "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", - "│ └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo", - "└─HashJoin(Probe) 15609.38 root inner join, equal:[eq(test.t2.b, test.t3.b)]", + "HashJoin 24389.65 root inner join, equal:[eq(test.t2.b, test.t3.b)]", + "├─TableReader(Build) 9990.00 root partition:all data:Selection", + "│ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.b))", + "│ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", + "└─HashJoin(Probe) 19511.72 root inner join, equal:[eq(test.t1.b, test.t2.b)]", " ├─TableReader(Build) 9990.00 root partition:all data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t3.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t3 keep order:false, stats:pseudo", - " └─HashJoin(Probe) 12487.50 root inner join, equal:[eq(test.t1.b, test.t2.b)]", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 15609.38 root right outer join, left side:HashJoin, equal:[eq(test.t.a, test.t1.a)]", " ├─TableReader(Build) 9990.00 root partition:all data:Selection", - " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.b))", - " │ └─TableFullScan 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo", - " └─TableReader(Probe) 9990.00 root partition:all data:Selection", - " └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", - " └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo" + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12487.50 root inner join, equal:[eq(test.t4.a, test.t.a)]", + " ├─TableReader(Build) 9990.00 root partition:all data:Selection", + " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t.a))", + " │ └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo", + " └─TableReader(Probe) 9990.00 root partition:all data:Selection", + " └─Selection 9990.00 cop[tikv] not(isnull(test.t4.a))", + " └─TableFullScan 10000.00 cop[tikv] table:t4 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" @@ -1100,24 +1092,19 @@ "Plan": [ "TableReader 15609.38 root MppVersion: 3, data:ExchangeSender", "└─ExchangeSender 15609.38 mpp[tiflash] ExchangeType: PassThrough", - " └─HashJoin 15609.38 mpp[tiflash] left outer join, left side:ExchangeReceiver, equal:[eq(test.t2.b, test.t1.b)]", - " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", - " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t2.b, collate: binary]", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", - " └─ExchangeReceiver(Probe) 12487.50 mpp[tiflash] ", - " └─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.b, collate: binary]", - " └─HashJoin 12487.50 mpp[tiflash] left outer join, left side:Selection, equal:[eq(test.t1.a, test.t3.a)]", - " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", - " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t3.a))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo", - " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t1.b))", - " └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo" + " └─HashJoin 15609.38 mpp[tiflash] left outer join, left side:HashJoin, equal:[eq(test.t1.a, test.t3.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t3.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12487.50 mpp[tiflash] left outer join, left side:TableFullScan, equal:[eq(test.t2.b, test.t1.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─TableFullScan(Probe) 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" ], - "Warning": [ - "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid", - "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" - ] + "Warning": null }, { "SQL": "select /*+ leading(t2, t3) */ * from t2 left join (t1 join t3 on t1.a=t3.a join t4 on t3.b = t4.b) on t2.b=t1.b;", @@ -1144,7 +1131,6 @@ " └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo" ], "Warning": [ - "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid", "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" ] }, @@ -1153,13 +1139,13 @@ "Plan": [ "TableReader 19492.21 root MppVersion: 3, data:ExchangeSender", "└─ExchangeSender 19492.21 mpp[tiflash] ExchangeType: PassThrough", - " └─HashJoin 19492.21 mpp[tiflash] left outer join, left side:ExchangeReceiver, equal:[eq(test.t2.b, test.t1.b)]", - " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", - " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t2.b, collate: binary]", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", - " └─ExchangeReceiver(Probe) 15593.77 mpp[tiflash] ", - " └─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.b, collate: binary]", - " └─Projection 15593.77 mpp[tiflash] test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b", + " └─Projection 19492.21 mpp[tiflash] test.t2.a, test.t2.b, test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b", + " └─HashJoin 19492.21 mpp[tiflash] left outer join, left side:ExchangeReceiver, equal:[eq(test.t2.b, test.t1.b)]", + " ├─ExchangeReceiver(Build) 10000.00 mpp[tiflash] ", + " │ └─ExchangeSender 10000.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t2.b, collate: binary]", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 15593.77 mpp[tiflash] ", + " └─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.b, collate: binary]", " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t3.a, test.t1.a)]", " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", @@ -1181,36 +1167,35 @@ "TableReader 30426.12 root MppVersion: 3, data:ExchangeSender", "└─ExchangeSender 30426.12 mpp[tiflash] ExchangeType: PassThrough", " └─Projection 30426.12 mpp[tiflash] test.t2.a, test.t2.b, test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b, test.t5.a, test.t5.b, test.t6.a, test.t6.b", - " └─HashJoin 30426.12 mpp[tiflash] left outer join, left side:ExchangeReceiver, equal:[eq(test.t2.b, test.t1.b)]", - " ├─ExchangeReceiver(Build) 15593.77 mpp[tiflash] ", - " │ └─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t2.b, collate: binary]", - " │ └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t5.b, test.t6.b)]", - " │ ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", - " │ │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t6.b))", - " │ │ └─TableFullScan 10000.00 mpp[tiflash] table:t6 keep order:false, stats:pseudo", - " │ └─HashJoin(Probe) 12475.01 mpp[tiflash] inner join, equal:[eq(test.t5.a, test.t2.a)]", - " │ ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", - " │ │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t5.a)), not(isnull(test.t5.b))", - " │ │ └─TableFullScan 10000.00 mpp[tiflash] table:t5 keep order:false, stats:pseudo", - " │ └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t2.a))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", - " └─ExchangeReceiver(Probe) 15593.77 mpp[tiflash] ", - " └─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.b, collate: binary]", - " └─Projection 15593.77 mpp[tiflash] test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b", - " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t3.a, test.t1.a)]", - " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", - " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", - " └─HashJoin(Probe) 12475.01 mpp[tiflash] inner join, equal:[eq(test.t3.b, test.t4.b)]", + " └─HashJoin 30426.12 mpp[tiflash] inner join, equal:[eq(test.t5.b, test.t6.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t6.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t6 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 24340.89 mpp[tiflash] inner join, equal:[eq(test.t2.a, test.t5.a)]", + " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", + " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t5.a)), not(isnull(test.t5.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t5 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 19492.21 mpp[tiflash] left outer join, left side:ExchangeReceiver, equal:[eq(test.t2.b, test.t1.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t2.b, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t2.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 15593.77 mpp[tiflash] ", + " └─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.b, collate: binary]", + " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t3.a, test.t1.a)]", " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo", - " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t4.b))", - " └─TableFullScan 10000.00 mpp[tiflash] table:t4 keep order:false, stats:pseudo" + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12475.01 mpp[tiflash] inner join, equal:[eq(test.t3.b, test.t4.b)]", + " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", + " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t4.b))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t4 keep order:false, stats:pseudo" ], "Warning": null }, @@ -1219,36 +1204,35 @@ "Plan": [ "TableReader 30426.12 root MppVersion: 3, data:ExchangeSender", "└─ExchangeSender 30426.12 mpp[tiflash] ExchangeType: PassThrough", - " └─Projection 30426.12 mpp[tiflash] test.t2.a, test.t2.b, test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b, test.t5.a, test.t5.b, test.t6.a, test.t6.b", - " └─HashJoin 30426.12 mpp[tiflash] left outer join, left side:ExchangeReceiver, equal:[eq(test.t2.b, test.t1.b)]", - " ├─ExchangeReceiver(Build) 15593.77 mpp[tiflash] ", - " │ └─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t2.b, collate: binary]", - " │ └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t5.b, test.t6.b)]", - " │ ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", - " │ │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t6.b))", - " │ │ └─TableFullScan 10000.00 mpp[tiflash] table:t6 keep order:false, stats:pseudo", - " │ └─HashJoin(Probe) 12475.01 mpp[tiflash] inner join, equal:[eq(test.t5.a, test.t2.a)]", - " │ ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", - " │ │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t5.a)), not(isnull(test.t5.b))", - " │ │ └─TableFullScan 10000.00 mpp[tiflash] table:t5 keep order:false, stats:pseudo", - " │ └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t2.a))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", - " └─ExchangeReceiver(Probe) 15593.77 mpp[tiflash] ", - " └─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.b, collate: binary]", - " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t3.b, test.t4.b)]", - " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", - " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t4.b))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t4 keep order:false, stats:pseudo", - " └─HashJoin(Probe) 12475.01 mpp[tiflash] inner join, equal:[eq(test.t1.a, test.t3.a)]", - " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", - " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", - " └─Selection(Probe) 9980.01 mpp[tiflash] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - " └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo" + " └─HashJoin 30426.12 mpp[tiflash] inner join, equal:[eq(test.t5.b, test.t6.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t6.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t6 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 24340.89 mpp[tiflash] inner join, equal:[eq(test.t2.a, test.t5.a)]", + " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", + " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t5.a)), not(isnull(test.t5.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t5 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 19492.21 mpp[tiflash] left outer join, left side:ExchangeReceiver, equal:[eq(test.t2.b, test.t1.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t2.b, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t2.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 15593.77 mpp[tiflash] ", + " └─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.b, collate: binary]", + " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t3.b, test.t4.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t4.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t4 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12475.01 mpp[tiflash] inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", + " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─Selection(Probe) 9980.01 mpp[tiflash] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid" @@ -1259,39 +1243,37 @@ "Plan": [ "TableReader 30426.12 root MppVersion: 3, data:ExchangeSender", "└─ExchangeSender 30426.12 mpp[tiflash] ExchangeType: PassThrough", - " └─Projection 30426.12 mpp[tiflash] test.t2.a, test.t2.b, test.t1.a, test.t1.b, test.t3.a, test.t3.b, test.t4.a, test.t4.b, test.t5.a, test.t5.b, test.t6.a, test.t6.b", - " └─HashJoin 30426.12 mpp[tiflash] left outer join, left side:ExchangeReceiver, equal:[eq(test.t2.b, test.t1.b)]", - " ├─ExchangeReceiver(Build) 15593.77 mpp[tiflash] ", - " │ └─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t2.b, collate: binary]", - " │ └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t5.b, test.t6.b)]", - " │ ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", - " │ │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t6.b))", - " │ │ └─TableFullScan 10000.00 mpp[tiflash] table:t6 keep order:false, stats:pseudo", - " │ └─HashJoin(Probe) 12475.01 mpp[tiflash] inner join, equal:[eq(test.t5.a, test.t2.a)]", - " │ ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", - " │ │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t5.a)), not(isnull(test.t5.b))", - " │ │ └─TableFullScan 10000.00 mpp[tiflash] table:t5 keep order:false, stats:pseudo", - " │ └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t2.a))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", - " └─ExchangeReceiver(Probe) 15593.77 mpp[tiflash] ", - " └─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.b, collate: binary]", - " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t3.b, test.t4.b)]", - " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", - " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t4.b))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t4 keep order:false, stats:pseudo", - " └─HashJoin(Probe) 12475.01 mpp[tiflash] inner join, equal:[eq(test.t1.a, test.t3.a)]", - " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", - " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", - " └─Selection(Probe) 9980.01 mpp[tiflash] not(isnull(test.t3.a)), not(isnull(test.t3.b))", - " └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo" + " └─HashJoin 30426.12 mpp[tiflash] inner join, equal:[eq(test.t5.b, test.t6.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t6.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t6 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 24340.89 mpp[tiflash] inner join, equal:[eq(test.t2.a, test.t5.a)]", + " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", + " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t5.a)), not(isnull(test.t5.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t5 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 19492.21 mpp[tiflash] left outer join, left side:ExchangeReceiver, equal:[eq(test.t2.b, test.t1.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t2.b, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t2.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 15593.77 mpp[tiflash] ", + " └─ExchangeSender 15593.77 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.b, collate: binary]", + " └─HashJoin 15593.77 mpp[tiflash] inner join, equal:[eq(test.t3.b, test.t4.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t4.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t4 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12475.01 mpp[tiflash] inner join, equal:[eq(test.t1.a, test.t3.a)]", + " ├─ExchangeReceiver(Build) 9980.01 mpp[tiflash] ", + " │ └─ExchangeSender 9980.01 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9980.01 mpp[tiflash] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─Selection(Probe) 9980.01 mpp[tiflash] not(isnull(test.t3.a)), not(isnull(test.t3.b))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo" ], "Warning": [ - "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid", "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" ] }, @@ -1365,30 +1347,30 @@ "Plan": [ "TableReader 24389.65 root MppVersion: 3, data:ExchangeSender", "└─ExchangeSender 24389.65 mpp[tiflash] ExchangeType: PassThrough", - " └─HashJoin 24389.65 mpp[tiflash] right outer join, left side:ExchangeReceiver, equal:[eq(test.t.a, test.t1.a)]", - " ├─ExchangeReceiver(Build) 12487.50 mpp[tiflash] ", - " │ └─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", - " │ └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t4.a, test.t.a)]", - " │ ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", - " │ │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t4.a))", - " │ │ └─TableFullScan 10000.00 mpp[tiflash] table:t4 keep order:false, stats:pseudo", - " │ └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo", - " └─ExchangeReceiver(Probe) 15609.38 mpp[tiflash] ", - " └─ExchangeSender 15609.38 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.a, collate: binary]", - " └─HashJoin 15609.38 mpp[tiflash] inner join, equal:[eq(test.t2.b, test.t3.b)]", - " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", - " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t3.b))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo", - " └─HashJoin(Probe) 12487.50 mpp[tiflash] inner join, equal:[eq(test.t1.b, test.t2.b)]", - " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", - " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t1.b))", - " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", - " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t2.b))", - " └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo" + " └─HashJoin 24389.65 mpp[tiflash] inner join, equal:[eq(test.t2.b, test.t3.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t3.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t3 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 19511.72 mpp[tiflash] inner join, equal:[eq(test.t1.b, test.t2.b)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t2.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t2 keep order:false, stats:pseudo", + " └─HashJoin(Probe) 15609.38 mpp[tiflash] right outer join, left side:ExchangeReceiver, equal:[eq(test.t.a, test.t1.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t1.a, collate: binary]", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t1.b))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t1 keep order:false, stats:pseudo", + " └─ExchangeReceiver(Probe) 12487.50 mpp[tiflash] ", + " └─ExchangeSender 12487.50 mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.t.a, collate: binary]", + " └─HashJoin 12487.50 mpp[tiflash] inner join, equal:[eq(test.t4.a, test.t.a)]", + " ├─ExchangeReceiver(Build) 9990.00 mpp[tiflash] ", + " │ └─ExchangeSender 9990.00 mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ └─Selection 9990.00 mpp[tiflash] not(isnull(test.t4.a))", + " │ └─TableFullScan 10000.00 mpp[tiflash] table:t4 keep order:false, stats:pseudo", + " └─Selection(Probe) 9990.00 mpp[tiflash] not(isnull(test.t.a))", + " └─TableFullScan 10000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" ], "Warning": [ "Warning 1815 leading hint is inapplicable, check if the leading hint table is valid" diff --git a/pkg/planner/core/casetest/rule/testdata/order_aware_join_reorder_suite_in.json b/pkg/planner/core/casetest/rule/testdata/order_aware_join_reorder_suite_in.json new file mode 100644 index 0000000000000..5b707ab4d415e --- /dev/null +++ b/pkg/planner/core/casetest/rule/testdata/order_aware_join_reorder_suite_in.json @@ -0,0 +1,36 @@ +[ + { + "name": "TestOrderAwareCDCJoinReorder", + "cases": [ + "SELECT t6.id, t7.payload, t8.payload FROM t7 JOIN t8 ON t7.id = t8.id JOIN t6 ON t6.id = t7.id WHERE t6.category = 'hot' ORDER BY t6.id LIMIT 2", + "SELECT /*+ LEADING(t7, t8, t6) */ t6.id, t7.payload, t8.payload FROM t7 JOIN t8 ON t7.id = t8.id JOIN t6 ON t6.id = t7.id WHERE t6.category = 'hot' ORDER BY t6.id LIMIT 2", + "SELECT /*+ TIDB_INLJ(t7, t8, t9) */ t6.id, t7.payload, t8.payload, t9.payload FROM t7 JOIN t8 ON t7.id = t8.id JOIN t9 ON t8.id = t9.id JOIN t6 ON t6.id = t7.id WHERE t6.category = 'hot' ORDER BY t6.id LIMIT 2", + "SELECT /*+ TIDB_INLJ(t7, t8, t9) LEADING(t7, t8, t9, t6) */ t6.id, t7.payload, t8.payload, t9.payload FROM t7 JOIN t8 ON t7.id = t8.id JOIN t9 ON t8.id = t9.id JOIN t6 ON t6.id = t7.id WHERE t6.category = 'hot' ORDER BY t6.id LIMIT 2" + ] + }, + { + "name": "TestOrderAwareJoinReorderPushSelection", + "cases": [ + "set @@tidb_opt_enable_alternative_logical_plans = 0", + "explain format = 'plan_tree' select t6.id, t7.payload, t8.payload, t9.payload from t7 join t8 on t7.id = t8.id join t9 on t8.id = t9.id join t6 on t6.id = t7.id where t6.category = 'hot' and t9.payload = 1 order by t6.id limit 2", + "set @@tidb_opt_enable_alternative_logical_plans = 1", + "explain format = 'plan_tree' select t6.id, t7.payload, t8.payload, t9.payload from t7 join t8 on t7.id = t8.id join t9 on t8.id = t9.id join t6 on t6.id = t7.id where t6.category = 'hot' and t9.payload = 1 order by t6.id limit 2" + ] + }, + { + "name": "TestOrderAwareJoinReorderAlternativeRound", + "cases": [ + "set @@tidb_opt_join_reorder_through_sel = 1", + "set @@tidb_opt_enable_alternative_logical_plans = 1", + "explain format = 'plan_tree' select oa_order_t1.created_at, oa_order_t4.payload from oa_order_t2 join oa_order_t3 on oa_order_t3.t2_id = oa_order_t2.id join oa_order_t1 on oa_order_t1.id = oa_order_t2.t1_id join oa_order_t4 on oa_order_t4.t3_id = oa_order_t3.id where oa_order_t1.category = 'hot' and oa_order_t4.payload = 1 order by oa_order_t1.created_at limit 2", + "set @@tidb_opt_enable_alternative_logical_plans = 0", + "explain format = 'plan_tree' select oa_order_t1.created_at, oa_order_t4.payload from oa_order_t2 join oa_order_t3 on oa_order_t3.t2_id = oa_order_t2.id join oa_order_t1 on oa_order_t1.id = oa_order_t2.t1_id join oa_order_t4 on oa_order_t4.t3_id = oa_order_t3.id where oa_order_t1.category = 'hot' and oa_order_t4.payload = 1 order by oa_order_t1.created_at limit 2", + "set @@tidb_opt_enable_alternative_logical_plans = 1", + "explain format = 'plan_tree' select /*+ LEADING(oa_order_t1, oa_order_t2, oa_order_t3, oa_order_t4) TIDB_INLJ(oa_order_t2, oa_order_t3, oa_order_t4) */ oa_order_t1.created_at, oa_order_t4.payload from oa_order_t2 join oa_order_t3 on oa_order_t3.t2_id = oa_order_t2.id join oa_order_t1 on oa_order_t1.id = oa_order_t2.t1_id join oa_order_t4 on oa_order_t4.t3_id = oa_order_t3.id where oa_order_t1.category = 'hot' and oa_order_t4.payload = 1 order by oa_order_t1.created_at limit 2", + "set @@tidb_opt_enable_alternative_logical_plans = 0", + "explain format = 'plan_tree' select o.txt_val, o.label from obj o join relationship r on o.id = r.ref_ojb_id join obj o1 on o1.id = r.obj_id where o1.type_id = 1 order by o.label limit 1", + "set @@tidb_opt_enable_alternative_logical_plans = 1", + "explain format = 'plan_tree' select o.txt_val, o.label from obj o join relationship r on o.id = r.ref_ojb_id join obj o1 on o1.id = r.obj_id where o1.type_id = 1 order by o.label limit 1" + ] + } +] diff --git a/pkg/planner/core/casetest/rule/testdata/order_aware_join_reorder_suite_out.json b/pkg/planner/core/casetest/rule/testdata/order_aware_join_reorder_suite_out.json new file mode 100644 index 0000000000000..ffae8bb2b4cc7 --- /dev/null +++ b/pkg/planner/core/casetest/rule/testdata/order_aware_join_reorder_suite_out.json @@ -0,0 +1,266 @@ +[ + { + "Name": "TestOrderAwareCDCJoinReorder", + "Cases": [ + { + "SQL": "SELECT t6.id, t7.payload, t8.payload FROM t7 JOIN t8 ON t7.id = t8.id JOIN t6 ON t6.id = t7.id WHERE t6.category = 'hot' ORDER BY t6.id LIMIT 2", + "Plan": [ + "Projection root test.t6.id, test.t7.payload, test.t8.payload", + "└─TopN root test.t6.id, offset:0, count:2", + " └─Projection root test.t7.payload, test.t8.payload, test.t6.id", + " └─MergeJoin root inner join, left key:test.t7.id, right key:test.t8.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t8 keep order:true", + " └─MergeJoin(Probe) root inner join, left key:test.t6.id, right key:test.t7.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t7 keep order:true", + " └─IndexReader(Probe) root index:IndexRangeScan", + " └─IndexRangeScan cop[tikv] table:t6, index:idx_category_id_payload(category, id, payload) range:[\"hot\",\"hot\"], keep order:true" + ], + "Result": [ + "1 100 1000", + "2 200 2000" + ] + }, + { + "SQL": "SELECT /*+ LEADING(t7, t8, t6) */ t6.id, t7.payload, t8.payload FROM t7 JOIN t8 ON t7.id = t8.id JOIN t6 ON t6.id = t7.id WHERE t6.category = 'hot' ORDER BY t6.id LIMIT 2", + "Plan": [ + "Projection root test.t6.id, test.t7.payload, test.t8.payload", + "└─Limit root offset:0, count:2", + " └─MergeJoin root inner join, left key:test.t7.id, right key:test.t6.id", + " ├─IndexReader(Build) root index:IndexRangeScan", + " │ └─IndexRangeScan cop[tikv] table:t6, index:idx_category_id_payload(category, id, payload) range:[\"hot\",\"hot\"], keep order:true", + " └─MergeJoin(Probe) root inner join, left key:test.t7.id, right key:test.t8.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t8 keep order:true", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t7 keep order:true" + ], + "Result": [ + "1 100 1000", + "2 200 2000" + ] + }, + { + "SQL": "SELECT /*+ TIDB_INLJ(t7, t8, t9) */ t6.id, t7.payload, t8.payload, t9.payload FROM t7 JOIN t8 ON t7.id = t8.id JOIN t9 ON t8.id = t9.id JOIN t6 ON t6.id = t7.id WHERE t6.category = 'hot' ORDER BY t6.id LIMIT 2", + "Plan": [ + "Projection root test.t6.id, test.t7.payload, test.t8.payload, test.t9.payload", + "└─Limit root offset:0, count:2", + " └─Projection root test.t7.payload, test.t8.payload, test.t9.payload, test.t6.id", + " └─IndexJoin root inner join, inner:TableReader, outer key:test.t8.id, inner key:test.t9.id, equal cond:eq(test.t8.id, test.t9.id)", + " ├─IndexJoin(Build) root inner join, inner:TableReader, outer key:test.t7.id, inner key:test.t8.id, equal cond:eq(test.t7.id, test.t8.id)", + " │ ├─IndexJoin(Build) root inner join, inner:TableReader, outer key:test.t6.id, inner key:test.t7.id, equal cond:eq(test.t6.id, test.t7.id)", + " │ │ ├─IndexReader(Build) root index:IndexRangeScan", + " │ │ │ └─IndexRangeScan cop[tikv] table:t6, index:idx_category_id_payload(category, id, payload) range:[\"hot\",\"hot\"], keep order:true", + " │ │ └─TableReader(Probe) root data:TableRangeScan", + " │ │ └─TableRangeScan cop[tikv] table:t7 range: decided by [test.t6.id], keep order:false", + " │ └─TableReader(Probe) root data:TableRangeScan", + " │ └─TableRangeScan cop[tikv] table:t8 range: decided by [test.t7.id], keep order:false", + " └─TableReader(Probe) root data:TableRangeScan", + " └─TableRangeScan cop[tikv] table:t9 range: decided by [test.t8.id], keep order:false" + ], + "Result": [ + "1 100 1000 10000", + "2 200 2000 20000" + ] + }, + { + "SQL": "SELECT /*+ TIDB_INLJ(t7, t8, t9) LEADING(t7, t8, t9, t6) */ t6.id, t7.payload, t8.payload, t9.payload FROM t7 JOIN t8 ON t7.id = t8.id JOIN t9 ON t8.id = t9.id JOIN t6 ON t6.id = t7.id WHERE t6.category = 'hot' ORDER BY t6.id LIMIT 2", + "Plan": [ + "Projection root test.t6.id, test.t7.payload, test.t8.payload, test.t9.payload", + "└─Limit root offset:0, count:2", + " └─MergeJoin root inner join, left key:test.t7.id, right key:test.t6.id", + " ├─IndexReader(Build) root index:IndexRangeScan", + " │ └─IndexRangeScan cop[tikv] table:t6, index:idx_category_id_payload(category, id, payload) range:[\"hot\",\"hot\"], keep order:true", + " └─IndexJoin(Probe) root inner join, inner:TableReader, outer key:test.t8.id, inner key:test.t9.id, equal cond:eq(test.t8.id, test.t9.id)", + " ├─IndexJoin(Build) root inner join, inner:TableReader, outer key:test.t7.id, inner key:test.t8.id, equal cond:eq(test.t7.id, test.t8.id)", + " │ ├─TableReader(Build) root data:TableFullScan", + " │ │ └─TableFullScan cop[tikv] table:t7 keep order:true", + " │ └─TableReader(Probe) root data:TableRangeScan", + " │ └─TableRangeScan cop[tikv] table:t8 range: decided by [test.t7.id], keep order:false", + " └─TableReader(Probe) root data:TableRangeScan", + " └─TableRangeScan cop[tikv] table:t9 range: decided by [test.t8.id], keep order:false" + ], + "Result": [ + "1 100 1000 10000", + "2 200 2000 20000" + ] + } + ] + }, + { + "Name": "TestOrderAwareJoinReorderPushSelection", + "Cases": [ + { + "SQL": "set @@tidb_opt_enable_alternative_logical_plans = 0", + "Plan": null + }, + { + "SQL": "explain format = 'plan_tree' select t6.id, t7.payload, t8.payload, t9.payload from t7 join t8 on t7.id = t8.id join t9 on t8.id = t9.id join t6 on t6.id = t7.id where t6.category = 'hot' and t9.payload = 1 order by t6.id limit 2", + "Plan": [ + "Projection root test.t6.id, test.t7.payload, test.t8.payload, test.t9.payload", + "└─TopN root test.t6.id, offset:0, count:2", + " └─Projection root test.t7.payload, test.t8.payload, test.t9.payload, test.t6.id", + " └─IndexJoin root inner join, inner:IndexReader, outer key:test.t7.id, inner key:test.t6.id, equal cond:eq(test.t7.id, test.t6.id)", + " ├─IndexHashJoin(Build) root inner join, inner:IndexLookUp, outer key:test.t8.id, inner key:test.t7.id, equal cond:eq(test.t8.id, test.t7.id)", + " │ ├─IndexJoin(Build) root inner join, inner:IndexLookUp, outer key:test.t9.id, inner key:test.t8.id, equal cond:eq(test.t9.id, test.t8.id)", + " │ │ ├─IndexReader(Build) root index:IndexRangeScan", + " │ │ │ └─IndexRangeScan cop[tikv] table:t9, index:idx_payload_id(payload, id) range:[1,1], keep order:false", + " │ │ └─IndexLookUp(Probe) root ", + " │ │ ├─IndexRangeScan(Build) cop[tikv] table:t8, index:idx_id(id) range: decided by [eq(test.t8.id, test.t9.id)], keep order:false", + " │ │ └─TableRowIDScan(Probe) cop[tikv] table:t8 keep order:false", + " │ └─IndexLookUp(Probe) root ", + " │ ├─IndexRangeScan(Build) cop[tikv] table:t7, index:idx_id(id) range: decided by [eq(test.t7.id, test.t8.id)], keep order:false", + " │ └─TableRowIDScan(Probe) cop[tikv] table:t7 keep order:false", + " └─IndexReader(Probe) root index:IndexRangeScan", + " └─IndexRangeScan cop[tikv] table:t6, index:idx_category_id_payload(category, id, payload) range: decided by [eq(test.t6.id, test.t7.id) eq(test.t6.category, hot)], keep order:false" + ] + }, + { + "SQL": "set @@tidb_opt_enable_alternative_logical_plans = 1", + "Plan": null + }, + { + "SQL": "explain format = 'plan_tree' select t6.id, t7.payload, t8.payload, t9.payload from t7 join t8 on t7.id = t8.id join t9 on t8.id = t9.id join t6 on t6.id = t7.id where t6.category = 'hot' and t9.payload = 1 order by t6.id limit 2", + "Plan": [ + "Projection root test.t6.id, test.t7.payload, test.t8.payload, test.t9.payload", + "└─Limit root offset:0, count:2", + " └─Projection root test.t7.payload, test.t8.payload, test.t9.payload, test.t6.id", + " └─IndexJoin root inner join, inner:IndexReader, outer key:test.t8.id, inner key:test.t9.id, equal cond:eq(test.t8.id, test.t9.id)", + " ├─IndexHashJoin(Build) root inner join, inner:IndexLookUp, outer key:test.t7.id, inner key:test.t8.id, equal cond:eq(test.t7.id, test.t8.id)", + " │ ├─IndexHashJoin(Build) root inner join, inner:IndexLookUp, outer key:test.t6.id, inner key:test.t7.id, equal cond:eq(test.t6.id, test.t7.id)", + " │ │ ├─IndexReader(Build) root index:IndexRangeScan", + " │ │ │ └─IndexRangeScan cop[tikv] table:t6, index:idx_category_id_payload(category, id, payload) range:[\"hot\",\"hot\"], keep order:true", + " │ │ └─IndexLookUp(Probe) root ", + " │ │ ├─IndexRangeScan(Build) cop[tikv] table:t7, index:idx_id(id) range: decided by [eq(test.t7.id, test.t6.id)], keep order:false", + " │ │ └─TableRowIDScan(Probe) cop[tikv] table:t7 keep order:false", + " │ └─IndexLookUp(Probe) root ", + " │ ├─IndexRangeScan(Build) cop[tikv] table:t8, index:idx_id(id) range: decided by [eq(test.t8.id, test.t7.id)], keep order:false", + " │ └─TableRowIDScan(Probe) cop[tikv] table:t8 keep order:false", + " └─IndexReader(Probe) root index:IndexRangeScan", + " └─IndexRangeScan cop[tikv] table:t9, index:idx_payload_id(payload, id) range: decided by [eq(test.t9.id, test.t8.id) eq(test.t9.payload, 1)], keep order:false" + ] + } + ] + }, + { + "Name": "TestOrderAwareJoinReorderAlternativeRound", + "Cases": [ + { + "SQL": "set @@tidb_opt_join_reorder_through_sel = 1", + "Plan": null + }, + { + "SQL": "set @@tidb_opt_enable_alternative_logical_plans = 1", + "Plan": null + }, + { + "SQL": "explain format = 'plan_tree' select oa_order_t1.created_at, oa_order_t4.payload from oa_order_t2 join oa_order_t3 on oa_order_t3.t2_id = oa_order_t2.id join oa_order_t1 on oa_order_t1.id = oa_order_t2.t1_id join oa_order_t4 on oa_order_t4.t3_id = oa_order_t3.id where oa_order_t1.category = 'hot' and oa_order_t4.payload = 1 order by oa_order_t1.created_at limit 2", + "Plan": [ + "Limit root offset:0, count:2", + "└─IndexJoin root inner join, inner:IndexReader, outer key:test.oa_order_t3.id, inner key:test.oa_order_t4.t3_id, equal cond:eq(test.oa_order_t3.id, test.oa_order_t4.t3_id)", + " ├─IndexHashJoin(Build) root inner join, inner:IndexReader, outer key:test.oa_order_t2.id, inner key:test.oa_order_t3.t2_id, equal cond:eq(test.oa_order_t2.id, test.oa_order_t3.t2_id)", + " │ ├─IndexJoin(Build) root inner join, inner:IndexReader, outer key:test.oa_order_t1.id, inner key:test.oa_order_t2.t1_id, equal cond:eq(test.oa_order_t1.id, test.oa_order_t2.t1_id)", + " │ │ ├─IndexReader(Build) root index:IndexRangeScan", + " │ │ │ └─IndexRangeScan cop[tikv] table:oa_order_t1, index:idx_category_created(category, created_at, id) range:[\"hot\",\"hot\"], keep order:true", + " │ │ └─IndexReader(Probe) root index:IndexRangeScan", + " │ │ └─IndexRangeScan cop[tikv] table:oa_order_t2, index:idx_t1_id(t1_id) range: decided by [eq(test.oa_order_t2.t1_id, test.oa_order_t1.id)], keep order:false", + " │ └─IndexReader(Probe) root index:IndexRangeScan", + " │ └─IndexRangeScan cop[tikv] table:oa_order_t3, index:idx_t2_id(t2_id) range: decided by [eq(test.oa_order_t3.t2_id, test.oa_order_t2.id)], keep order:false", + " └─IndexReader(Probe) root index:IndexRangeScan", + " └─IndexRangeScan cop[tikv] table:oa_order_t4, index:idx_payload_t3(payload, t3_id) range: decided by [eq(test.oa_order_t4.t3_id, test.oa_order_t3.id) eq(test.oa_order_t4.payload, 1)], keep order:false" + ] + }, + { + "SQL": "set @@tidb_opt_enable_alternative_logical_plans = 0", + "Plan": null + }, + { + "SQL": "explain format = 'plan_tree' select oa_order_t1.created_at, oa_order_t4.payload from oa_order_t2 join oa_order_t3 on oa_order_t3.t2_id = oa_order_t2.id join oa_order_t1 on oa_order_t1.id = oa_order_t2.t1_id join oa_order_t4 on oa_order_t4.t3_id = oa_order_t3.id where oa_order_t1.category = 'hot' and oa_order_t4.payload = 1 order by oa_order_t1.created_at limit 2", + "Plan": [ + "TopN root test.oa_order_t1.created_at, offset:0, count:2", + "└─Projection root test.oa_order_t1.created_at, test.oa_order_t4.payload", + " └─IndexHashJoin root inner join, inner:TableReader, outer key:test.oa_order_t2.t1_id, inner key:test.oa_order_t1.id, equal cond:eq(test.oa_order_t2.t1_id, test.oa_order_t1.id)", + " ├─IndexJoin(Build) root inner join, inner:TableReader, outer key:test.oa_order_t3.t2_id, inner key:test.oa_order_t2.id, equal cond:eq(test.oa_order_t3.t2_id, test.oa_order_t2.id)", + " │ ├─MergeJoin(Build) root inner join, left key:test.oa_order_t4.t3_id, right key:test.oa_order_t3.id", + " │ │ ├─TableReader(Build) root data:TableFullScan", + " │ │ │ └─TableFullScan cop[tikv] table:oa_order_t3 keep order:true", + " │ │ └─IndexReader(Probe) root index:IndexRangeScan", + " │ │ └─IndexRangeScan cop[tikv] table:oa_order_t4, index:idx_payload_t3(payload, t3_id) range:[1,1], keep order:true", + " │ └─TableReader(Probe) root data:TableRangeScan", + " │ └─TableRangeScan cop[tikv] table:oa_order_t2 range: decided by [test.oa_order_t3.t2_id], keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] eq(test.oa_order_t1.category, \"hot\")", + " └─TableRangeScan cop[tikv] table:oa_order_t1 range: decided by [test.oa_order_t2.t1_id], keep order:false" + ] + }, + { + "SQL": "set @@tidb_opt_enable_alternative_logical_plans = 1", + "Plan": null + }, + { + "SQL": "explain format = 'plan_tree' select /*+ LEADING(oa_order_t1, oa_order_t2, oa_order_t3, oa_order_t4) TIDB_INLJ(oa_order_t2, oa_order_t3, oa_order_t4) */ oa_order_t1.created_at, oa_order_t4.payload from oa_order_t2 join oa_order_t3 on oa_order_t3.t2_id = oa_order_t2.id join oa_order_t1 on oa_order_t1.id = oa_order_t2.t1_id join oa_order_t4 on oa_order_t4.t3_id = oa_order_t3.id where oa_order_t1.category = 'hot' and oa_order_t4.payload = 1 order by oa_order_t1.created_at limit 2", + "Plan": [ + "Limit root offset:0, count:2", + "└─IndexJoin root inner join, inner:IndexReader, outer key:test.oa_order_t3.id, inner key:test.oa_order_t4.t3_id, equal cond:eq(test.oa_order_t3.id, test.oa_order_t4.t3_id)", + " ├─IndexJoin(Build) root inner join, inner:IndexReader, outer key:test.oa_order_t2.id, inner key:test.oa_order_t3.t2_id, equal cond:eq(test.oa_order_t2.id, test.oa_order_t3.t2_id)", + " │ ├─IndexJoin(Build) root inner join, inner:IndexReader, outer key:test.oa_order_t1.id, inner key:test.oa_order_t2.t1_id, equal cond:eq(test.oa_order_t1.id, test.oa_order_t2.t1_id)", + " │ │ ├─IndexReader(Build) root index:IndexRangeScan", + " │ │ │ └─IndexRangeScan cop[tikv] table:oa_order_t1, index:idx_category_created(category, created_at, id) range:[\"hot\",\"hot\"], keep order:true", + " │ │ └─IndexReader(Probe) root index:IndexRangeScan", + " │ │ └─IndexRangeScan cop[tikv] table:oa_order_t2, index:idx_t1_id(t1_id) range: decided by [eq(test.oa_order_t2.t1_id, test.oa_order_t1.id)], keep order:false", + " │ └─IndexReader(Probe) root index:IndexRangeScan", + " │ └─IndexRangeScan cop[tikv] table:oa_order_t3, index:idx_t2_id(t2_id) range: decided by [eq(test.oa_order_t3.t2_id, test.oa_order_t2.id)], keep order:false", + " └─IndexReader(Probe) root index:IndexRangeScan", + " └─IndexRangeScan cop[tikv] table:oa_order_t4, index:idx_payload_t3(payload, t3_id) range: decided by [eq(test.oa_order_t4.t3_id, test.oa_order_t3.id) eq(test.oa_order_t4.payload, 1)], keep order:false" + ] + }, + { + "SQL": "set @@tidb_opt_enable_alternative_logical_plans = 0", + "Plan": null + }, + { + "SQL": "explain format = 'plan_tree' select o.txt_val, o.label from obj o join relationship r on o.id = r.ref_ojb_id join obj o1 on o1.id = r.obj_id where o1.type_id = 1 order by o.label limit 1", + "Plan": [ + "Projection root test.obj.txt_val, test.obj.label", + "└─TopN root test.obj.label, offset:0, count:1", + " └─IndexHashJoin root inner join, inner:IndexLookUp, outer key:test.relationship.ref_ojb_id, inner key:test.obj.id, equal cond:eq(test.relationship.ref_ojb_id, test.obj.id)", + " ├─HashJoin(Build) root inner join, equal:[eq(test.relationship.obj_id, test.obj.id)]", + " │ ├─IndexReader(Build) root index:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.relationship.ref_ojb_id))", + " │ │ └─IndexFullScan cop[tikv] table:r, index:idx_obj_id(obj_id, ref_ojb_id) keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] eq(test.obj.type_id, 1)", + " │ └─TableFullScan cop[tikv] table:o1 keep order:false", + " └─IndexLookUp(Probe) root ", + " ├─IndexRangeScan(Build) cop[tikv] table:o, index:idx_id(id) range: decided by [eq(test.obj.id, test.relationship.ref_ojb_id)], keep order:false", + " └─TableRowIDScan(Probe) cop[tikv] table:o keep order:false" + ] + }, + { + "SQL": "set @@tidb_opt_enable_alternative_logical_plans = 1", + "Plan": null + }, + { + "SQL": "explain format = 'plan_tree' select o.txt_val, o.label from obj o join relationship r on o.id = r.ref_ojb_id join obj o1 on o1.id = r.obj_id where o1.type_id = 1 order by o.label limit 1", + "Plan": [ + "Projection root test.obj.txt_val, test.obj.label", + "└─Limit root offset:0, count:1", + " └─IndexJoin root inner join, inner:IndexLookUp, outer key:test.relationship.obj_id, inner key:test.obj.id, equal cond:eq(test.relationship.obj_id, test.obj.id)", + " ├─IndexJoin(Build) root inner join, inner:IndexReader, outer key:test.obj.id, inner key:test.relationship.ref_ojb_id, equal cond:eq(test.obj.id, test.relationship.ref_ojb_id)", + " │ ├─Projection(Build) root test.obj.id, test.obj.label, test.obj.txt_val", + " │ │ └─IndexLookUp root ", + " │ │ ├─IndexFullScan(Build) cop[tikv] table:o, index:idx_label(label) keep order:true", + " │ │ └─TableRowIDScan(Probe) cop[tikv] table:o keep order:false", + " │ └─IndexReader(Probe) root index:Selection", + " │ └─Selection cop[tikv] not(isnull(test.relationship.ref_ojb_id))", + " │ └─IndexRangeScan cop[tikv] table:r, index:idx_ref_obj_id(ref_ojb_id, obj_id) range: decided by [eq(test.relationship.ref_ojb_id, test.obj.id) not(isnull(test.relationship.obj_id))], keep order:false", + " └─IndexLookUp(Probe) root ", + " ├─IndexRangeScan(Build) cop[tikv] table:o1, index:idx_id(id) range: decided by [eq(test.obj.id, test.relationship.obj_id)], keep order:false", + " └─Selection(Probe) cop[tikv] eq(test.obj.type_id, 1)", + " └─TableRowIDScan cop[tikv] table:o1 keep order:false" + ] + } + ] + } +] diff --git a/pkg/planner/core/casetest/rule/testdata/order_aware_join_reorder_suite_xut.json b/pkg/planner/core/casetest/rule/testdata/order_aware_join_reorder_suite_xut.json new file mode 100644 index 0000000000000..ffae8bb2b4cc7 --- /dev/null +++ b/pkg/planner/core/casetest/rule/testdata/order_aware_join_reorder_suite_xut.json @@ -0,0 +1,266 @@ +[ + { + "Name": "TestOrderAwareCDCJoinReorder", + "Cases": [ + { + "SQL": "SELECT t6.id, t7.payload, t8.payload FROM t7 JOIN t8 ON t7.id = t8.id JOIN t6 ON t6.id = t7.id WHERE t6.category = 'hot' ORDER BY t6.id LIMIT 2", + "Plan": [ + "Projection root test.t6.id, test.t7.payload, test.t8.payload", + "└─TopN root test.t6.id, offset:0, count:2", + " └─Projection root test.t7.payload, test.t8.payload, test.t6.id", + " └─MergeJoin root inner join, left key:test.t7.id, right key:test.t8.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t8 keep order:true", + " └─MergeJoin(Probe) root inner join, left key:test.t6.id, right key:test.t7.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t7 keep order:true", + " └─IndexReader(Probe) root index:IndexRangeScan", + " └─IndexRangeScan cop[tikv] table:t6, index:idx_category_id_payload(category, id, payload) range:[\"hot\",\"hot\"], keep order:true" + ], + "Result": [ + "1 100 1000", + "2 200 2000" + ] + }, + { + "SQL": "SELECT /*+ LEADING(t7, t8, t6) */ t6.id, t7.payload, t8.payload FROM t7 JOIN t8 ON t7.id = t8.id JOIN t6 ON t6.id = t7.id WHERE t6.category = 'hot' ORDER BY t6.id LIMIT 2", + "Plan": [ + "Projection root test.t6.id, test.t7.payload, test.t8.payload", + "└─Limit root offset:0, count:2", + " └─MergeJoin root inner join, left key:test.t7.id, right key:test.t6.id", + " ├─IndexReader(Build) root index:IndexRangeScan", + " │ └─IndexRangeScan cop[tikv] table:t6, index:idx_category_id_payload(category, id, payload) range:[\"hot\",\"hot\"], keep order:true", + " └─MergeJoin(Probe) root inner join, left key:test.t7.id, right key:test.t8.id", + " ├─TableReader(Build) root data:TableFullScan", + " │ └─TableFullScan cop[tikv] table:t8 keep order:true", + " └─TableReader(Probe) root data:TableFullScan", + " └─TableFullScan cop[tikv] table:t7 keep order:true" + ], + "Result": [ + "1 100 1000", + "2 200 2000" + ] + }, + { + "SQL": "SELECT /*+ TIDB_INLJ(t7, t8, t9) */ t6.id, t7.payload, t8.payload, t9.payload FROM t7 JOIN t8 ON t7.id = t8.id JOIN t9 ON t8.id = t9.id JOIN t6 ON t6.id = t7.id WHERE t6.category = 'hot' ORDER BY t6.id LIMIT 2", + "Plan": [ + "Projection root test.t6.id, test.t7.payload, test.t8.payload, test.t9.payload", + "└─Limit root offset:0, count:2", + " └─Projection root test.t7.payload, test.t8.payload, test.t9.payload, test.t6.id", + " └─IndexJoin root inner join, inner:TableReader, outer key:test.t8.id, inner key:test.t9.id, equal cond:eq(test.t8.id, test.t9.id)", + " ├─IndexJoin(Build) root inner join, inner:TableReader, outer key:test.t7.id, inner key:test.t8.id, equal cond:eq(test.t7.id, test.t8.id)", + " │ ├─IndexJoin(Build) root inner join, inner:TableReader, outer key:test.t6.id, inner key:test.t7.id, equal cond:eq(test.t6.id, test.t7.id)", + " │ │ ├─IndexReader(Build) root index:IndexRangeScan", + " │ │ │ └─IndexRangeScan cop[tikv] table:t6, index:idx_category_id_payload(category, id, payload) range:[\"hot\",\"hot\"], keep order:true", + " │ │ └─TableReader(Probe) root data:TableRangeScan", + " │ │ └─TableRangeScan cop[tikv] table:t7 range: decided by [test.t6.id], keep order:false", + " │ └─TableReader(Probe) root data:TableRangeScan", + " │ └─TableRangeScan cop[tikv] table:t8 range: decided by [test.t7.id], keep order:false", + " └─TableReader(Probe) root data:TableRangeScan", + " └─TableRangeScan cop[tikv] table:t9 range: decided by [test.t8.id], keep order:false" + ], + "Result": [ + "1 100 1000 10000", + "2 200 2000 20000" + ] + }, + { + "SQL": "SELECT /*+ TIDB_INLJ(t7, t8, t9) LEADING(t7, t8, t9, t6) */ t6.id, t7.payload, t8.payload, t9.payload FROM t7 JOIN t8 ON t7.id = t8.id JOIN t9 ON t8.id = t9.id JOIN t6 ON t6.id = t7.id WHERE t6.category = 'hot' ORDER BY t6.id LIMIT 2", + "Plan": [ + "Projection root test.t6.id, test.t7.payload, test.t8.payload, test.t9.payload", + "└─Limit root offset:0, count:2", + " └─MergeJoin root inner join, left key:test.t7.id, right key:test.t6.id", + " ├─IndexReader(Build) root index:IndexRangeScan", + " │ └─IndexRangeScan cop[tikv] table:t6, index:idx_category_id_payload(category, id, payload) range:[\"hot\",\"hot\"], keep order:true", + " └─IndexJoin(Probe) root inner join, inner:TableReader, outer key:test.t8.id, inner key:test.t9.id, equal cond:eq(test.t8.id, test.t9.id)", + " ├─IndexJoin(Build) root inner join, inner:TableReader, outer key:test.t7.id, inner key:test.t8.id, equal cond:eq(test.t7.id, test.t8.id)", + " │ ├─TableReader(Build) root data:TableFullScan", + " │ │ └─TableFullScan cop[tikv] table:t7 keep order:true", + " │ └─TableReader(Probe) root data:TableRangeScan", + " │ └─TableRangeScan cop[tikv] table:t8 range: decided by [test.t7.id], keep order:false", + " └─TableReader(Probe) root data:TableRangeScan", + " └─TableRangeScan cop[tikv] table:t9 range: decided by [test.t8.id], keep order:false" + ], + "Result": [ + "1 100 1000 10000", + "2 200 2000 20000" + ] + } + ] + }, + { + "Name": "TestOrderAwareJoinReorderPushSelection", + "Cases": [ + { + "SQL": "set @@tidb_opt_enable_alternative_logical_plans = 0", + "Plan": null + }, + { + "SQL": "explain format = 'plan_tree' select t6.id, t7.payload, t8.payload, t9.payload from t7 join t8 on t7.id = t8.id join t9 on t8.id = t9.id join t6 on t6.id = t7.id where t6.category = 'hot' and t9.payload = 1 order by t6.id limit 2", + "Plan": [ + "Projection root test.t6.id, test.t7.payload, test.t8.payload, test.t9.payload", + "└─TopN root test.t6.id, offset:0, count:2", + " └─Projection root test.t7.payload, test.t8.payload, test.t9.payload, test.t6.id", + " └─IndexJoin root inner join, inner:IndexReader, outer key:test.t7.id, inner key:test.t6.id, equal cond:eq(test.t7.id, test.t6.id)", + " ├─IndexHashJoin(Build) root inner join, inner:IndexLookUp, outer key:test.t8.id, inner key:test.t7.id, equal cond:eq(test.t8.id, test.t7.id)", + " │ ├─IndexJoin(Build) root inner join, inner:IndexLookUp, outer key:test.t9.id, inner key:test.t8.id, equal cond:eq(test.t9.id, test.t8.id)", + " │ │ ├─IndexReader(Build) root index:IndexRangeScan", + " │ │ │ └─IndexRangeScan cop[tikv] table:t9, index:idx_payload_id(payload, id) range:[1,1], keep order:false", + " │ │ └─IndexLookUp(Probe) root ", + " │ │ ├─IndexRangeScan(Build) cop[tikv] table:t8, index:idx_id(id) range: decided by [eq(test.t8.id, test.t9.id)], keep order:false", + " │ │ └─TableRowIDScan(Probe) cop[tikv] table:t8 keep order:false", + " │ └─IndexLookUp(Probe) root ", + " │ ├─IndexRangeScan(Build) cop[tikv] table:t7, index:idx_id(id) range: decided by [eq(test.t7.id, test.t8.id)], keep order:false", + " │ └─TableRowIDScan(Probe) cop[tikv] table:t7 keep order:false", + " └─IndexReader(Probe) root index:IndexRangeScan", + " └─IndexRangeScan cop[tikv] table:t6, index:idx_category_id_payload(category, id, payload) range: decided by [eq(test.t6.id, test.t7.id) eq(test.t6.category, hot)], keep order:false" + ] + }, + { + "SQL": "set @@tidb_opt_enable_alternative_logical_plans = 1", + "Plan": null + }, + { + "SQL": "explain format = 'plan_tree' select t6.id, t7.payload, t8.payload, t9.payload from t7 join t8 on t7.id = t8.id join t9 on t8.id = t9.id join t6 on t6.id = t7.id where t6.category = 'hot' and t9.payload = 1 order by t6.id limit 2", + "Plan": [ + "Projection root test.t6.id, test.t7.payload, test.t8.payload, test.t9.payload", + "└─Limit root offset:0, count:2", + " └─Projection root test.t7.payload, test.t8.payload, test.t9.payload, test.t6.id", + " └─IndexJoin root inner join, inner:IndexReader, outer key:test.t8.id, inner key:test.t9.id, equal cond:eq(test.t8.id, test.t9.id)", + " ├─IndexHashJoin(Build) root inner join, inner:IndexLookUp, outer key:test.t7.id, inner key:test.t8.id, equal cond:eq(test.t7.id, test.t8.id)", + " │ ├─IndexHashJoin(Build) root inner join, inner:IndexLookUp, outer key:test.t6.id, inner key:test.t7.id, equal cond:eq(test.t6.id, test.t7.id)", + " │ │ ├─IndexReader(Build) root index:IndexRangeScan", + " │ │ │ └─IndexRangeScan cop[tikv] table:t6, index:idx_category_id_payload(category, id, payload) range:[\"hot\",\"hot\"], keep order:true", + " │ │ └─IndexLookUp(Probe) root ", + " │ │ ├─IndexRangeScan(Build) cop[tikv] table:t7, index:idx_id(id) range: decided by [eq(test.t7.id, test.t6.id)], keep order:false", + " │ │ └─TableRowIDScan(Probe) cop[tikv] table:t7 keep order:false", + " │ └─IndexLookUp(Probe) root ", + " │ ├─IndexRangeScan(Build) cop[tikv] table:t8, index:idx_id(id) range: decided by [eq(test.t8.id, test.t7.id)], keep order:false", + " │ └─TableRowIDScan(Probe) cop[tikv] table:t8 keep order:false", + " └─IndexReader(Probe) root index:IndexRangeScan", + " └─IndexRangeScan cop[tikv] table:t9, index:idx_payload_id(payload, id) range: decided by [eq(test.t9.id, test.t8.id) eq(test.t9.payload, 1)], keep order:false" + ] + } + ] + }, + { + "Name": "TestOrderAwareJoinReorderAlternativeRound", + "Cases": [ + { + "SQL": "set @@tidb_opt_join_reorder_through_sel = 1", + "Plan": null + }, + { + "SQL": "set @@tidb_opt_enable_alternative_logical_plans = 1", + "Plan": null + }, + { + "SQL": "explain format = 'plan_tree' select oa_order_t1.created_at, oa_order_t4.payload from oa_order_t2 join oa_order_t3 on oa_order_t3.t2_id = oa_order_t2.id join oa_order_t1 on oa_order_t1.id = oa_order_t2.t1_id join oa_order_t4 on oa_order_t4.t3_id = oa_order_t3.id where oa_order_t1.category = 'hot' and oa_order_t4.payload = 1 order by oa_order_t1.created_at limit 2", + "Plan": [ + "Limit root offset:0, count:2", + "└─IndexJoin root inner join, inner:IndexReader, outer key:test.oa_order_t3.id, inner key:test.oa_order_t4.t3_id, equal cond:eq(test.oa_order_t3.id, test.oa_order_t4.t3_id)", + " ├─IndexHashJoin(Build) root inner join, inner:IndexReader, outer key:test.oa_order_t2.id, inner key:test.oa_order_t3.t2_id, equal cond:eq(test.oa_order_t2.id, test.oa_order_t3.t2_id)", + " │ ├─IndexJoin(Build) root inner join, inner:IndexReader, outer key:test.oa_order_t1.id, inner key:test.oa_order_t2.t1_id, equal cond:eq(test.oa_order_t1.id, test.oa_order_t2.t1_id)", + " │ │ ├─IndexReader(Build) root index:IndexRangeScan", + " │ │ │ └─IndexRangeScan cop[tikv] table:oa_order_t1, index:idx_category_created(category, created_at, id) range:[\"hot\",\"hot\"], keep order:true", + " │ │ └─IndexReader(Probe) root index:IndexRangeScan", + " │ │ └─IndexRangeScan cop[tikv] table:oa_order_t2, index:idx_t1_id(t1_id) range: decided by [eq(test.oa_order_t2.t1_id, test.oa_order_t1.id)], keep order:false", + " │ └─IndexReader(Probe) root index:IndexRangeScan", + " │ └─IndexRangeScan cop[tikv] table:oa_order_t3, index:idx_t2_id(t2_id) range: decided by [eq(test.oa_order_t3.t2_id, test.oa_order_t2.id)], keep order:false", + " └─IndexReader(Probe) root index:IndexRangeScan", + " └─IndexRangeScan cop[tikv] table:oa_order_t4, index:idx_payload_t3(payload, t3_id) range: decided by [eq(test.oa_order_t4.t3_id, test.oa_order_t3.id) eq(test.oa_order_t4.payload, 1)], keep order:false" + ] + }, + { + "SQL": "set @@tidb_opt_enable_alternative_logical_plans = 0", + "Plan": null + }, + { + "SQL": "explain format = 'plan_tree' select oa_order_t1.created_at, oa_order_t4.payload from oa_order_t2 join oa_order_t3 on oa_order_t3.t2_id = oa_order_t2.id join oa_order_t1 on oa_order_t1.id = oa_order_t2.t1_id join oa_order_t4 on oa_order_t4.t3_id = oa_order_t3.id where oa_order_t1.category = 'hot' and oa_order_t4.payload = 1 order by oa_order_t1.created_at limit 2", + "Plan": [ + "TopN root test.oa_order_t1.created_at, offset:0, count:2", + "└─Projection root test.oa_order_t1.created_at, test.oa_order_t4.payload", + " └─IndexHashJoin root inner join, inner:TableReader, outer key:test.oa_order_t2.t1_id, inner key:test.oa_order_t1.id, equal cond:eq(test.oa_order_t2.t1_id, test.oa_order_t1.id)", + " ├─IndexJoin(Build) root inner join, inner:TableReader, outer key:test.oa_order_t3.t2_id, inner key:test.oa_order_t2.id, equal cond:eq(test.oa_order_t3.t2_id, test.oa_order_t2.id)", + " │ ├─MergeJoin(Build) root inner join, left key:test.oa_order_t4.t3_id, right key:test.oa_order_t3.id", + " │ │ ├─TableReader(Build) root data:TableFullScan", + " │ │ │ └─TableFullScan cop[tikv] table:oa_order_t3 keep order:true", + " │ │ └─IndexReader(Probe) root index:IndexRangeScan", + " │ │ └─IndexRangeScan cop[tikv] table:oa_order_t4, index:idx_payload_t3(payload, t3_id) range:[1,1], keep order:true", + " │ └─TableReader(Probe) root data:TableRangeScan", + " │ └─TableRangeScan cop[tikv] table:oa_order_t2 range: decided by [test.oa_order_t3.t2_id], keep order:false", + " └─TableReader(Probe) root data:Selection", + " └─Selection cop[tikv] eq(test.oa_order_t1.category, \"hot\")", + " └─TableRangeScan cop[tikv] table:oa_order_t1 range: decided by [test.oa_order_t2.t1_id], keep order:false" + ] + }, + { + "SQL": "set @@tidb_opt_enable_alternative_logical_plans = 1", + "Plan": null + }, + { + "SQL": "explain format = 'plan_tree' select /*+ LEADING(oa_order_t1, oa_order_t2, oa_order_t3, oa_order_t4) TIDB_INLJ(oa_order_t2, oa_order_t3, oa_order_t4) */ oa_order_t1.created_at, oa_order_t4.payload from oa_order_t2 join oa_order_t3 on oa_order_t3.t2_id = oa_order_t2.id join oa_order_t1 on oa_order_t1.id = oa_order_t2.t1_id join oa_order_t4 on oa_order_t4.t3_id = oa_order_t3.id where oa_order_t1.category = 'hot' and oa_order_t4.payload = 1 order by oa_order_t1.created_at limit 2", + "Plan": [ + "Limit root offset:0, count:2", + "└─IndexJoin root inner join, inner:IndexReader, outer key:test.oa_order_t3.id, inner key:test.oa_order_t4.t3_id, equal cond:eq(test.oa_order_t3.id, test.oa_order_t4.t3_id)", + " ├─IndexJoin(Build) root inner join, inner:IndexReader, outer key:test.oa_order_t2.id, inner key:test.oa_order_t3.t2_id, equal cond:eq(test.oa_order_t2.id, test.oa_order_t3.t2_id)", + " │ ├─IndexJoin(Build) root inner join, inner:IndexReader, outer key:test.oa_order_t1.id, inner key:test.oa_order_t2.t1_id, equal cond:eq(test.oa_order_t1.id, test.oa_order_t2.t1_id)", + " │ │ ├─IndexReader(Build) root index:IndexRangeScan", + " │ │ │ └─IndexRangeScan cop[tikv] table:oa_order_t1, index:idx_category_created(category, created_at, id) range:[\"hot\",\"hot\"], keep order:true", + " │ │ └─IndexReader(Probe) root index:IndexRangeScan", + " │ │ └─IndexRangeScan cop[tikv] table:oa_order_t2, index:idx_t1_id(t1_id) range: decided by [eq(test.oa_order_t2.t1_id, test.oa_order_t1.id)], keep order:false", + " │ └─IndexReader(Probe) root index:IndexRangeScan", + " │ └─IndexRangeScan cop[tikv] table:oa_order_t3, index:idx_t2_id(t2_id) range: decided by [eq(test.oa_order_t3.t2_id, test.oa_order_t2.id)], keep order:false", + " └─IndexReader(Probe) root index:IndexRangeScan", + " └─IndexRangeScan cop[tikv] table:oa_order_t4, index:idx_payload_t3(payload, t3_id) range: decided by [eq(test.oa_order_t4.t3_id, test.oa_order_t3.id) eq(test.oa_order_t4.payload, 1)], keep order:false" + ] + }, + { + "SQL": "set @@tidb_opt_enable_alternative_logical_plans = 0", + "Plan": null + }, + { + "SQL": "explain format = 'plan_tree' select o.txt_val, o.label from obj o join relationship r on o.id = r.ref_ojb_id join obj o1 on o1.id = r.obj_id where o1.type_id = 1 order by o.label limit 1", + "Plan": [ + "Projection root test.obj.txt_val, test.obj.label", + "└─TopN root test.obj.label, offset:0, count:1", + " └─IndexHashJoin root inner join, inner:IndexLookUp, outer key:test.relationship.ref_ojb_id, inner key:test.obj.id, equal cond:eq(test.relationship.ref_ojb_id, test.obj.id)", + " ├─HashJoin(Build) root inner join, equal:[eq(test.relationship.obj_id, test.obj.id)]", + " │ ├─IndexReader(Build) root index:Selection", + " │ │ └─Selection cop[tikv] not(isnull(test.relationship.ref_ojb_id))", + " │ │ └─IndexFullScan cop[tikv] table:r, index:idx_obj_id(obj_id, ref_ojb_id) keep order:false", + " │ └─TableReader(Probe) root data:Selection", + " │ └─Selection cop[tikv] eq(test.obj.type_id, 1)", + " │ └─TableFullScan cop[tikv] table:o1 keep order:false", + " └─IndexLookUp(Probe) root ", + " ├─IndexRangeScan(Build) cop[tikv] table:o, index:idx_id(id) range: decided by [eq(test.obj.id, test.relationship.ref_ojb_id)], keep order:false", + " └─TableRowIDScan(Probe) cop[tikv] table:o keep order:false" + ] + }, + { + "SQL": "set @@tidb_opt_enable_alternative_logical_plans = 1", + "Plan": null + }, + { + "SQL": "explain format = 'plan_tree' select o.txt_val, o.label from obj o join relationship r on o.id = r.ref_ojb_id join obj o1 on o1.id = r.obj_id where o1.type_id = 1 order by o.label limit 1", + "Plan": [ + "Projection root test.obj.txt_val, test.obj.label", + "└─Limit root offset:0, count:1", + " └─IndexJoin root inner join, inner:IndexLookUp, outer key:test.relationship.obj_id, inner key:test.obj.id, equal cond:eq(test.relationship.obj_id, test.obj.id)", + " ├─IndexJoin(Build) root inner join, inner:IndexReader, outer key:test.obj.id, inner key:test.relationship.ref_ojb_id, equal cond:eq(test.obj.id, test.relationship.ref_ojb_id)", + " │ ├─Projection(Build) root test.obj.id, test.obj.label, test.obj.txt_val", + " │ │ └─IndexLookUp root ", + " │ │ ├─IndexFullScan(Build) cop[tikv] table:o, index:idx_label(label) keep order:true", + " │ │ └─TableRowIDScan(Probe) cop[tikv] table:o keep order:false", + " │ └─IndexReader(Probe) root index:Selection", + " │ └─Selection cop[tikv] not(isnull(test.relationship.ref_ojb_id))", + " │ └─IndexRangeScan cop[tikv] table:r, index:idx_ref_obj_id(ref_ojb_id, obj_id) range: decided by [eq(test.relationship.ref_ojb_id, test.obj.id) not(isnull(test.relationship.obj_id))], keep order:false", + " └─IndexLookUp(Probe) root ", + " ├─IndexRangeScan(Build) cop[tikv] table:o1, index:idx_id(id) range: decided by [eq(test.obj.id, test.relationship.obj_id)], keep order:false", + " └─Selection(Probe) cop[tikv] eq(test.obj.type_id, 1)", + " └─TableRowIDScan cop[tikv] table:o1 keep order:false" + ] + } + ] + } +] diff --git a/pkg/planner/core/casetest/rule/testdata/outer2inner_out.json b/pkg/planner/core/casetest/rule/testdata/outer2inner_out.json index bd363012da037..1809933472d24 100644 --- a/pkg/planner/core/casetest/rule/testdata/outer2inner_out.json +++ b/pkg/planner/core/casetest/rule/testdata/outer2inner_out.json @@ -167,11 +167,11 @@ { "SQL": "select * from t1 ta left outer join (t1 tb left outer join t1 tc on tb.b1 = tc.b1) on ta.a1=tc.a1; -- nested join. On clause is null filtering on tc.", "Plan": [ - "HashJoin 15593.77 root left outer join, left side:TableReader, equal:[eq(test.t1.a1, test.t1.a1)]", - "├─TableReader(Build) 10000.00 root data:TableFullScan", - "│ └─TableFullScan 10000.00 cop[tikv] table:ta keep order:false, stats:pseudo", - "└─Projection(Probe) 12475.01 root test.t1.a1, test.t1.b1, test.t1.c1, test.t1.a1, test.t1.b1, test.t1.c1", - " └─HashJoin 12475.01 root inner join, equal:[eq(test.t1.b1, test.t1.b1)]", + "Projection 15593.77 root test.t1.a1, test.t1.b1, test.t1.c1, test.t1.a1, test.t1.b1, test.t1.c1, test.t1.a1, test.t1.b1, test.t1.c1", + "└─HashJoin 15593.77 root left outer join, left side:TableReader, equal:[eq(test.t1.a1, test.t1.a1)]", + " ├─TableReader(Build) 10000.00 root data:TableFullScan", + " │ └─TableFullScan 10000.00 cop[tikv] table:ta keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t1.b1, test.t1.b1)]", " ├─TableReader(Build) 9980.01 root data:Selection", " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a1)), not(isnull(test.t1.b1))", " │ └─TableFullScan 10000.00 cop[tikv] table:tc keep order:false, stats:pseudo", diff --git a/pkg/planner/core/casetest/rule/testdata/outer2inner_xut.json b/pkg/planner/core/casetest/rule/testdata/outer2inner_xut.json index a3d52a60af4a7..a8ef18f548471 100644 --- a/pkg/planner/core/casetest/rule/testdata/outer2inner_xut.json +++ b/pkg/planner/core/casetest/rule/testdata/outer2inner_xut.json @@ -167,11 +167,11 @@ { "SQL": "select * from t1 ta left outer join (t1 tb left outer join t1 tc on tb.b1 = tc.b1) on ta.a1=tc.a1; -- nested join. On clause is null filtering on tc.", "Plan": [ - "HashJoin 15593.77 root left outer join, left side:TableReader, equal:[eq(test.t1.a1, test.t1.a1)]", - "├─TableReader(Build) 10000.00 root data:TableFullScan", - "│ └─TableFullScan 10000.00 cop[tikv] table:ta keep order:false, stats:pseudo", - "└─Projection(Probe) 12475.01 root test.t1.a1, test.t1.b1, test.t1.c1, test.t1.a1, test.t1.b1, test.t1.c1", - " └─HashJoin 12475.01 root inner join, equal:[eq(test.t1.b1, test.t1.b1)]", + "Projection 15593.77 root test.t1.a1, test.t1.b1, test.t1.c1, test.t1.a1, test.t1.b1, test.t1.c1, test.t1.a1, test.t1.b1, test.t1.c1", + "└─HashJoin 15593.77 root left outer join, left side:TableReader, equal:[eq(test.t1.a1, test.t1.a1)]", + " ├─TableReader(Build) 10000.00 root data:TableFullScan", + " │ └─TableFullScan 10000.00 cop[tikv] table:ta keep order:false, stats:pseudo", + " └─HashJoin(Probe) 12475.01 root inner join, equal:[eq(test.t1.b1, test.t1.b1)]", " ├─TableReader(Build) 9980.01 root data:Selection", " │ └─Selection 9980.01 cop[tikv] not(isnull(test.t1.a1)), not(isnull(test.t1.b1))", " │ └─TableFullScan 10000.00 cop[tikv] table:tc keep order:false, stats:pseudo", diff --git a/pkg/planner/core/casetest/rule/testdata/outer_to_semi_join_suite_out.json b/pkg/planner/core/casetest/rule/testdata/outer_to_semi_join_suite_out.json index dbce5b6c4dc4f..34130bd498d55 100644 --- a/pkg/planner/core/casetest/rule/testdata/outer_to_semi_join_suite_out.json +++ b/pkg/planner/core/casetest/rule/testdata/outer_to_semi_join_suite_out.json @@ -652,15 +652,15 @@ { "SQL": "SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t3.i = t2.i) ON t2.i = t1.i WHERE t3.i IS NULL", "Plan": [ - "Selection root isnull(test.t3.i)", - "└─HashJoin root left outer join, left side:TableReader, equal:[eq(test.t1.i, test.t2.i)]", + "Projection root test.t1.i, test.t2.i, ->test.t3.i", + "└─HashJoin root anti semi join, left side:HashJoin, equal:[eq(test.t2.i, test.t3.i)]", " ├─TableReader(Build) root data:TableFullScan", - " │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─HashJoin(Probe) root left outer join, left side:TableReader, equal:[eq(test.t2.i, test.t3.i)]", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo", + " └─HashJoin(Probe) root left outer join, left side:TableReader, equal:[eq(test.t1.i, test.t2.i)]", " ├─TableReader(Build) root data:TableFullScan", - " │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo", " └─TableReader(Probe) root data:TableFullScan", - " └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo" + " └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Result": [ "3 3 ", diff --git a/pkg/planner/core/casetest/rule/testdata/outer_to_semi_join_suite_xut.json b/pkg/planner/core/casetest/rule/testdata/outer_to_semi_join_suite_xut.json index dbce5b6c4dc4f..34130bd498d55 100644 --- a/pkg/planner/core/casetest/rule/testdata/outer_to_semi_join_suite_xut.json +++ b/pkg/planner/core/casetest/rule/testdata/outer_to_semi_join_suite_xut.json @@ -652,15 +652,15 @@ { "SQL": "SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t3.i = t2.i) ON t2.i = t1.i WHERE t3.i IS NULL", "Plan": [ - "Selection root isnull(test.t3.i)", - "└─HashJoin root left outer join, left side:TableReader, equal:[eq(test.t1.i, test.t2.i)]", + "Projection root test.t1.i, test.t2.i, ->test.t3.i", + "└─HashJoin root anti semi join, left side:HashJoin, equal:[eq(test.t2.i, test.t3.i)]", " ├─TableReader(Build) root data:TableFullScan", - " │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo", - " └─HashJoin(Probe) root left outer join, left side:TableReader, equal:[eq(test.t2.i, test.t3.i)]", + " │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo", + " └─HashJoin(Probe) root left outer join, left side:TableReader, equal:[eq(test.t1.i, test.t2.i)]", " ├─TableReader(Build) root data:TableFullScan", - " │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo", + " │ └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo", " └─TableReader(Probe) root data:TableFullScan", - " └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo" + " └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo" ], "Result": [ "3 3 ", diff --git a/pkg/planner/core/casetest/testdata/json_plan_suite_out.json b/pkg/planner/core/casetest/testdata/json_plan_suite_out.json index b07926585dc74..28191c5d3c582 100644 --- a/pkg/planner/core/casetest/testdata/json_plan_suite_out.json +++ b/pkg/planner/core/casetest/testdata/json_plan_suite_out.json @@ -105,7 +105,7 @@ "estRows": "12487.50", "actRows": "0", "taskType": "root", - "executeInfo": "time:113µs, open:29.5µs, close:3.85µs, loops:1", + "executeInfo": "time:327.6µs, open:84.4µs, close:8.42µs, loops:1", "operatorInfo": "inner join, left key:test.t1.id, right key:test.t2.id", "memoryInfo": "760 Bytes", "diskInfo": "0 Bytes", @@ -115,9 +115,9 @@ "estRows": "9990.00", "actRows": "0", "taskType": "root", - "executeInfo": "time:63.3µs, open:8.83µs, close:288ns, loops:1, cop_task: {num: 1, max: 36.7µs, proc_keys: 0, copr_cache_hit_ratio: 0.00, build_task_duration: 861ns, max_distsql_concurrency: 1}, fetch_resp_duration: 49.3µs, rpc_info:{Cop:{num_rpc:1, total_time:30.3µs}}", + "executeInfo": "time:176.8µs, open:19.1µs, close:795ns, loops:1, cop_task: {num: 1, max: 106.6µs, proc_keys: 0, copr_cache_hit_ratio: 0.00, build_task_duration: 2.19µs, max_distsql_concurrency: 1}, fetch_resp_duration: 140.4µs, rpc_info:{Cop:{num_rpc:1, total_time:91.7µs}}", "operatorInfo": "index:IndexFullScan_27", - "memoryInfo": "182 Bytes", + "memoryInfo": "198 Bytes", "diskInfo": "N/A", "subOperators": [ { @@ -126,7 +126,7 @@ "actRows": "0", "taskType": "cop[tikv]", "accessObject": "table:t2, index:id(id)", - "executeInfo": "tikv_task:{time:21.9µs, loops:0}", + "executeInfo": "tikv_task:{time:68.5µs, loops:0}", "operatorInfo": "keep order:true, stats:pseudo", "memoryInfo": "N/A", "diskInfo": "N/A" @@ -138,9 +138,9 @@ "estRows": "9990.00", "actRows": "0", "taskType": "root", - "executeInfo": "time:36.9µs, open:13µs, close:1.37µs, loops:1, cop_task: {num: 1, max: 16.6µs, proc_keys: 0, copr_cache_hit_ratio: 0.00, build_task_duration: 3.2µs, max_distsql_concurrency: 1}, fetch_resp_duration: 20.6µs, rpc_info:{Cop:{num_rpc:1, total_time:13.7µs}}", + "executeInfo": "time:113.6µs, open:35µs, close:5.13µs, loops:1, cop_task: {num: 1, max: 55.3µs, proc_keys: 0, copr_cache_hit_ratio: 0.00, build_task_duration: 9.96µs, max_distsql_concurrency: 1}, fetch_resp_duration: 68.8µs, rpc_info:{Cop:{num_rpc:1, total_time:46.5µs}}", "operatorInfo": "index:IndexFullScan_25", - "memoryInfo": "181 Bytes", + "memoryInfo": "198 Bytes", "diskInfo": "N/A", "subOperators": [ { @@ -149,7 +149,7 @@ "actRows": "0", "taskType": "cop[tikv]", "accessObject": "table:t1, index:id(id)", - "executeInfo": "tikv_task:{time:10µs, loops:0}", + "executeInfo": "tikv_task:{time:35.9µs, loops:0}", "operatorInfo": "keep order:true, stats:pseudo", "memoryInfo": "N/A", "diskInfo": "N/A" diff --git a/pkg/planner/core/casetest/testdata/json_plan_suite_xut.json b/pkg/planner/core/casetest/testdata/json_plan_suite_xut.json index a528fe1aba7ce..21cd830b731ed 100644 --- a/pkg/planner/core/casetest/testdata/json_plan_suite_xut.json +++ b/pkg/planner/core/casetest/testdata/json_plan_suite_xut.json @@ -105,7 +105,7 @@ "estRows": "12487.50", "actRows": "0", "taskType": "root", - "executeInfo": "time:117.6µs, open:32.2µs, close:3.63µs, loops:1", + "executeInfo": "time:368µs, open:83.8µs, close:8.94µs, loops:1", "operatorInfo": "inner join, left key:test.t1.id, right key:test.t2.id", "memoryInfo": "760 Bytes", "diskInfo": "0 Bytes", @@ -115,9 +115,9 @@ "estRows": "9990.00", "actRows": "0", "taskType": "root", - "executeInfo": "time:64µs, open:8.54µs, close:204ns, loops:1, cop_task: {num: 1, max: 38.6µs, proc_keys: 0, copr_cache_hit_ratio: 0.00, build_task_duration: 733ns, max_distsql_concurrency: 1}, fetch_resp_duration: 50.4µs, rpc_info:{Cop:{num_rpc:1, total_time:32µs}}", + "executeInfo": "time:186.8µs, open:22µs, close:1.01µs, loops:1, cop_task: {num: 1, max: 113.2µs, proc_keys: 0, copr_cache_hit_ratio: 0.00, build_task_duration: 5.44µs, max_distsql_concurrency: 1}, fetch_resp_duration: 142.6µs, rpc_info:{Cop:{num_rpc:1, total_time:95.9µs}}", "operatorInfo": "index:IndexFullScan_27", - "memoryInfo": "182 Bytes", + "memoryInfo": "198 Bytes", "diskInfo": "N/A", "subOperators": [ { @@ -126,7 +126,7 @@ "actRows": "0", "taskType": "cop[tikv]", "accessObject": "table:t2, index:id(id)", - "executeInfo": "tikv_task:{time:24.3µs, loops:0}", + "executeInfo": "tikv_task:{time:72.1µs, loops:0}", "operatorInfo": "keep order:true, stats:pseudo", "memoryInfo": "N/A", "diskInfo": "N/A" @@ -138,9 +138,9 @@ "estRows": "9990.00", "actRows": "0", "taskType": "root", - "executeInfo": "time:39.6µs, open:14.2µs, close:1.38µs, loops:1, cop_task: {num: 1, max: 18.8µs, proc_keys: 0, copr_cache_hit_ratio: 0.00, build_task_duration: 2.77µs, max_distsql_concurrency: 1}, fetch_resp_duration: 22µs, rpc_info:{Cop:{num_rpc:1, total_time:16µs}}", + "executeInfo": "time:144µs, open:33.6µs, close:4.65µs, loops:1, cop_task: {num: 1, max: 86.9µs, proc_keys: 0, copr_cache_hit_ratio: 0.00, build_task_duration: 10.6µs, max_distsql_concurrency: 1}, fetch_resp_duration: 99.9µs, rpc_info:{Cop:{num_rpc:1, total_time:72.2µs}}", "operatorInfo": "index:IndexFullScan_25", - "memoryInfo": "181 Bytes", + "memoryInfo": "198 Bytes", "diskInfo": "N/A", "subOperators": [ { @@ -149,7 +149,7 @@ "actRows": "0", "taskType": "cop[tikv]", "accessObject": "table:t1, index:id(id)", - "executeInfo": "tikv_task:{time:12µs, loops:0}", + "executeInfo": "tikv_task:{time:56.8µs, loops:0}", "operatorInfo": "keep order:true, stats:pseudo", "memoryInfo": "N/A", "diskInfo": "N/A" diff --git a/pkg/planner/core/casetest/tici/tici_test.go b/pkg/planner/core/casetest/tici/tici_test.go index f4fc0a6f5d8a5..542903ca2a0b8 100644 --- a/pkg/planner/core/casetest/tici/tici_test.go +++ b/pkg/planner/core/casetest/tici/tici_test.go @@ -243,15 +243,15 @@ func TestTiCIMatchAgainstValidation(t *testing.T) { // Non-BOOLEAN MODE is rejected. tk.MustContainErrMsg( "explain format='brief' select * from t1 where match(title) against ('hello')", - "Currently TiDB only supports BOOLEAN MODE in MATCH AGAINST", + "This version of TiDB doesn't yet support 'MATCH...AGAINST with this modifier on the native FTS path (modifier is not carried through pushdown to TiFlash)'", ) tk.MustContainErrMsg( "explain format='brief' select * from t1 where match(title) against ('hello' IN NATURAL LANGUAGE MODE)", - "Currently TiDB only supports BOOLEAN MODE in MATCH AGAINST", + "This version of TiDB doesn't yet support 'MATCH...AGAINST with this modifier on the native FTS path (modifier is not carried through pushdown to TiFlash)'", ) tk.MustContainErrMsg( "explain format='brief' select * from t1 where match(title) against ('hello' WITH QUERY EXPANSION)", - "Currently TiDB only supports BOOLEAN MODE in MATCH AGAINST", + "This version of TiDB doesn't yet support 'MATCH...AGAINST with this modifier on the native FTS path (modifier is not carried through pushdown to TiFlash)'", ) // BOOLEAN MODE should allow multiple SHOULD terms. With a no-score TiCI query, diff --git a/pkg/planner/core/casetest/tpcds/testdata/tpcds_suite_out.json b/pkg/planner/core/casetest/tpcds/testdata/tpcds_suite_out.json index 5615d9d0a6abb..540b6877e5905 100644 --- a/pkg/planner/core/casetest/tpcds/testdata/tpcds_suite_out.json +++ b/pkg/planner/core/casetest/tpcds/testdata/tpcds_suite_out.json @@ -25,129 +25,127 @@ " └─Projection mpp[tiflash] tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.item.i_item_sk, tpcds.item.i_product_name", " └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip", " └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_item_sk, tpcds.catalog_sales.cs_item_sk)]", - " ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_item_sk, collate: binary]", - " │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.income_band.ib_income_band_sk", - " │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.household_demographics.hd_income_band_sk, tpcds.income_band.ib_income_band_sk)]", - " │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.household_demographics.hd_income_band_sk, collate: binary]", - " │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.income_band.ib_income_band_sk", - " │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.household_demographics.hd_income_band_sk, tpcds.income_band.ib_income_band_sk)]", - " │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.household_demographics.hd_income_band_sk, collate: binary]", - " │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_address_sk", - " │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.customer.c_current_addr_sk, tpcds.customer_address.ca_address_sk)]", - " │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer.c_current_addr_sk, collate: binary]", - " │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_addr_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_address_sk", - " │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_addr_sk, tpcds.customer_address.ca_address_sk)]", - " │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_addr_sk, collate: binary]", - " │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_addr_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.promotion.p_promo_sk", - " │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_promo_sk, tpcds.promotion.p_promo_sk)]", - " │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_promo_sk, collate: binary]", - " │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_addr_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.date_dim.d_date_sk", - " │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.customer.c_first_shipto_date_sk, tpcds.date_dim.d_date_sk)]", - " │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer.c_first_shipto_date_sk, collate: binary]", - " │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.date_dim.d_year, tpcds.date_dim.d_date_sk", - " │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.customer.c_first_sales_date_sk, tpcds.date_dim.d_date_sk)]", - " │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer.c_first_sales_date_sk, collate: binary]", - " │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.store_returns.sr_item_sk, tpcds.store_returns.sr_ticket_number", - " │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_item_sk, tpcds.store_returns.sr_item_sk) eq(tpcds.store_sales.ss_ticket_number, tpcds.store_returns.sr_ticket_number)]", - " │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_item_sk, collate: binary], [name: tpcds.store_sales.ss_ticket_number, collate: binary]", - " │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_demo_sk", - " │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.customer.c_current_hdemo_sk, tpcds.household_demographics.hd_demo_sk)]", - " │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer.c_current_hdemo_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_hdemo_sk, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_demo_sk", - " │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_hdemo_sk, tpcds.household_demographics.hd_demo_sk)]", - " │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_hdemo_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_hdemo_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_hdemo_sk, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.customer_demographics.cd_demo_sk", - " │ │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.customer.c_current_cdemo_sk, tpcds.customer_demographics.cd_demo_sk)], other cond:ne(tpcds.customer_demographics.cd_marital_status, tpcds.customer_demographics.cd_marital_status)", - " │ │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer.c_current_cdemo_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_hdemo_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_cdemo_sk, tpcds.customer.c_current_hdemo_sk, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.customer_demographics.cd_marital_status, tpcds.customer_demographics.cd_demo_sk", - " │ │ │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_cdemo_sk, tpcds.customer_demographics.cd_demo_sk)]", - " │ │ │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_cdemo_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_cdemo_sk, tpcds.store_sales.ss_hdemo_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_cdemo_sk, tpcds.customer.c_current_hdemo_sk, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.store.s_store_sk", - " │ │ │ │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_store_sk, tpcds.store.s_store_sk)]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_store_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_cdemo_sk, tpcds.store_sales.ss_hdemo_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_store_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_cdemo_sk, tpcds.customer.c_current_hdemo_sk, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.customer.c_customer_sk", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_customer_sk, tpcds.customer.c_customer_sk)]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_customer_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_customer_sk, tpcds.store_sales.ss_cdemo_sk, tpcds.store_sales.ss_hdemo_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_store_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.date_dim.d_date_sk", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_sold_date_sk, tpcds.date_dim.d_date_sk)]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_sold_date_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk)]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.item.i_item_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] ge(tpcds.item.i_current_price, 35), ge(tpcds.item.i_current_price, 36), le(tpcds.item.i_current_price, 45), le(tpcds.item.i_current_price, 50)", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:item pushed down filter:in(tpcds.item.i_color, \"maroon\", \"burnished\", \"dim\", \"steel\", \"navajo\", \"chocolate\"), keep order:false, stats:pseudo", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_item_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.store_sales.ss_addr_sk)), not(isnull(tpcds.store_sales.ss_cdemo_sk)), not(isnull(tpcds.store_sales.ss_customer_sk)), not(isnull(tpcds.store_sales.ss_hdemo_sk)), not(isnull(tpcds.store_sales.ss_promo_sk)), not(isnull(tpcds.store_sales.ss_sold_date_sk)), not(isnull(tpcds.store_sales.ss_store_sk))", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:store_sales keep order:false, stats:pseudo", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.date_dim.d_date_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:d1 pushed down filter:or(eq(tpcds.date_dim.d_year, 2000), eq(tpcds.date_dim.d_year, 2001)), keep order:false, stats:pseudo", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer.c_customer_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.customer.c_current_addr_sk)), not(isnull(tpcds.customer.c_current_cdemo_sk)), not(isnull(tpcds.customer.c_current_hdemo_sk)), not(isnull(tpcds.customer.c_first_sales_date_sk)), not(isnull(tpcds.customer.c_first_shipto_date_sk))", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:customer keep order:false, stats:pseudo", - " │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store.s_store_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.store.s_store_name)), not(isnull(tpcds.store.s_zip))", - " │ │ │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:store keep order:false, stats:pseudo", - " │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer_demographics.cd_demo_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.customer_demographics.cd_marital_status))", - " │ │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:cd1 keep order:false, stats:pseudo", - " │ │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer_demographics.cd_demo_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.customer_demographics.cd_marital_status))", - " │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:cd2 keep order:false, stats:pseudo", - " │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.household_demographics.hd_demo_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.household_demographics.hd_income_band_sk))", - " │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:hd1 keep order:false, stats:pseudo", - " │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.household_demographics.hd_demo_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.household_demographics.hd_income_band_sk))", - " │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:hd2 keep order:false, stats:pseudo", - " │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_returns.sr_item_sk, collate: binary], [name: tpcds.store_returns.sr_ticket_number, collate: binary]", - " │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:store_returns keep order:false, stats:pseudo", - " │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.date_dim.d_date_sk, collate: binary]", - " │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:d2 keep order:false, stats:pseudo", - " │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.date_dim.d_date_sk, collate: binary]", - " │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:d3 keep order:false, stats:pseudo", - " │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.promotion.p_promo_sk, collate: binary]", - " │ │ │ │ │ └─TableFullScan mpp[tiflash] table:promotion keep order:false, stats:pseudo", - " │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer_address.ca_address_sk, collate: binary]", - " │ │ │ │ └─TableFullScan mpp[tiflash] table:ad1 keep order:false, stats:pseudo", - " │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer_address.ca_address_sk, collate: binary]", - " │ │ │ └─TableFullScan mpp[tiflash] table:ad2 keep order:false, stats:pseudo", - " │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.income_band.ib_income_band_sk, collate: binary]", - " │ │ └─TableFullScan mpp[tiflash] table:ib1 keep order:false, stats:pseudo", - " │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.income_band.ib_income_band_sk, collate: binary]", - " │ └─TableFullScan mpp[tiflash] table:ib2 keep order:false, stats:pseudo", + " ├─Projection(Build) mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.store_returns.sr_item_sk", + " │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_item_sk, tpcds.store_returns.sr_item_sk) eq(tpcds.store_sales.ss_ticket_number, tpcds.store_returns.sr_ticket_number)]", + " │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_item_sk, collate: binary]", + " │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.income_band.ib_income_band_sk", + " │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.household_demographics.hd_income_band_sk, tpcds.income_band.ib_income_band_sk)]", + " │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.household_demographics.hd_income_band_sk, collate: binary]", + " │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.income_band.ib_income_band_sk", + " │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.household_demographics.hd_income_band_sk, tpcds.income_band.ib_income_band_sk)]", + " │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.household_demographics.hd_income_band_sk, collate: binary]", + " │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_address_sk", + " │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.customer.c_current_addr_sk, tpcds.customer_address.ca_address_sk)]", + " │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer.c_current_addr_sk, collate: binary]", + " │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_addr_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_address_sk", + " │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_addr_sk, tpcds.customer_address.ca_address_sk)]", + " │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_addr_sk, collate: binary]", + " │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_addr_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.promotion.p_promo_sk", + " │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_promo_sk, tpcds.promotion.p_promo_sk)]", + " │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_promo_sk, collate: binary]", + " │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_addr_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.date_dim.d_date_sk", + " │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.customer.c_first_sales_date_sk, tpcds.date_dim.d_date_sk)]", + " │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer.c_first_sales_date_sk, collate: binary]", + " │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_sales_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.date_dim.d_year, tpcds.date_dim.d_date_sk", + " │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.customer.c_first_shipto_date_sk, tpcds.date_dim.d_date_sk)]", + " │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer.c_first_shipto_date_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_demo_sk", + " │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_hdemo_sk, tpcds.household_demographics.hd_demo_sk)]", + " │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_hdemo_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_hdemo_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.customer_demographics.cd_demo_sk", + " │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.customer.c_current_cdemo_sk, tpcds.customer_demographics.cd_demo_sk)], other cond:ne(tpcds.customer_demographics.cd_marital_status, tpcds.customer_demographics.cd_marital_status)", + " │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer.c_current_cdemo_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_hdemo_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_cdemo_sk, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.customer_demographics.cd_marital_status, tpcds.customer_demographics.cd_demo_sk", + " │ │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_cdemo_sk, tpcds.customer_demographics.cd_demo_sk)]", + " │ │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_cdemo_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_cdemo_sk, tpcds.store_sales.ss_hdemo_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_cdemo_sk, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_demo_sk", + " │ │ │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.customer.c_current_hdemo_sk, tpcds.household_demographics.hd_demo_sk)]", + " │ │ │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer.c_current_hdemo_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_cdemo_sk, tpcds.store_sales.ss_hdemo_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_cdemo_sk, tpcds.customer.c_current_hdemo_sk, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.store.s_store_sk", + " │ │ │ │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_store_sk, tpcds.store.s_store_sk)]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_store_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_cdemo_sk, tpcds.store_sales.ss_hdemo_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_store_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_cdemo_sk, tpcds.customer.c_current_hdemo_sk, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.customer.c_customer_sk", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_customer_sk, tpcds.customer.c_customer_sk)]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_customer_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_customer_sk, tpcds.store_sales.ss_cdemo_sk, tpcds.store_sales.ss_hdemo_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_store_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.date_dim.d_date_sk", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_sold_date_sk, tpcds.date_dim.d_date_sk)]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_sold_date_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk)]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.item.i_item_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] ge(tpcds.item.i_current_price, 35), ge(tpcds.item.i_current_price, 36), le(tpcds.item.i_current_price, 45), le(tpcds.item.i_current_price, 50)", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:item pushed down filter:in(tpcds.item.i_color, \"maroon\", \"burnished\", \"dim\", \"steel\", \"navajo\", \"chocolate\"), keep order:false, stats:pseudo", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_item_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.store_sales.ss_addr_sk)), not(isnull(tpcds.store_sales.ss_cdemo_sk)), not(isnull(tpcds.store_sales.ss_customer_sk)), not(isnull(tpcds.store_sales.ss_hdemo_sk)), not(isnull(tpcds.store_sales.ss_promo_sk)), not(isnull(tpcds.store_sales.ss_sold_date_sk)), not(isnull(tpcds.store_sales.ss_store_sk))", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:store_sales keep order:false, stats:pseudo", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.date_dim.d_date_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:d1 pushed down filter:or(eq(tpcds.date_dim.d_year, 2000), eq(tpcds.date_dim.d_year, 2001)), keep order:false, stats:pseudo", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer.c_customer_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.customer.c_current_addr_sk)), not(isnull(tpcds.customer.c_current_cdemo_sk)), not(isnull(tpcds.customer.c_current_hdemo_sk)), not(isnull(tpcds.customer.c_first_sales_date_sk)), not(isnull(tpcds.customer.c_first_shipto_date_sk))", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:customer keep order:false, stats:pseudo", + " │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store.s_store_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.store.s_store_name)), not(isnull(tpcds.store.s_zip))", + " │ │ │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:store keep order:false, stats:pseudo", + " │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.household_demographics.hd_demo_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.household_demographics.hd_income_band_sk))", + " │ │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:hd2 keep order:false, stats:pseudo", + " │ │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer_demographics.cd_demo_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.customer_demographics.cd_marital_status))", + " │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:cd1 keep order:false, stats:pseudo", + " │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer_demographics.cd_demo_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.customer_demographics.cd_marital_status))", + " │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:cd2 keep order:false, stats:pseudo", + " │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.household_demographics.hd_demo_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.household_demographics.hd_income_band_sk))", + " │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:hd1 keep order:false, stats:pseudo", + " │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.date_dim.d_date_sk, collate: binary]", + " │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:d3 keep order:false, stats:pseudo", + " │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.date_dim.d_date_sk, collate: binary]", + " │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:d2 keep order:false, stats:pseudo", + " │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.promotion.p_promo_sk, collate: binary]", + " │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:promotion keep order:false, stats:pseudo", + " │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer_address.ca_address_sk, collate: binary]", + " │ │ │ │ │ └─TableFullScan mpp[tiflash] table:ad1 keep order:false, stats:pseudo", + " │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer_address.ca_address_sk, collate: binary]", + " │ │ │ │ └─TableFullScan mpp[tiflash] table:ad2 keep order:false, stats:pseudo", + " │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.income_band.ib_income_band_sk, collate: binary]", + " │ │ │ └─TableFullScan mpp[tiflash] table:ib1 keep order:false, stats:pseudo", + " │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.income_band.ib_income_band_sk, collate: binary]", + " │ │ └─TableFullScan mpp[tiflash] table:ib2 keep order:false, stats:pseudo", + " │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_returns.sr_item_sk, collate: binary]", + " │ └─TableFullScan mpp[tiflash] table:store_returns keep order:false, stats:pseudo", " └─Selection(Probe) mpp[tiflash] gt(Column, mul(2, Column))", " └─Projection mpp[tiflash] Column, Column, tpcds.catalog_sales.cs_item_sk", " └─HashAgg mpp[tiflash] group by:Column, funcs:sum(Column)->Column, funcs:sum(Column)->Column, funcs:firstrow(Column)->tpcds.catalog_sales.cs_item_sk", diff --git a/pkg/planner/core/casetest/tpcds/testdata/tpcds_suite_xut.json b/pkg/planner/core/casetest/tpcds/testdata/tpcds_suite_xut.json index 5615d9d0a6abb..540b6877e5905 100644 --- a/pkg/planner/core/casetest/tpcds/testdata/tpcds_suite_xut.json +++ b/pkg/planner/core/casetest/tpcds/testdata/tpcds_suite_xut.json @@ -25,129 +25,127 @@ " └─Projection mpp[tiflash] tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.item.i_item_sk, tpcds.item.i_product_name", " └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip", " └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_item_sk, tpcds.catalog_sales.cs_item_sk)]", - " ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_item_sk, collate: binary]", - " │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.income_band.ib_income_band_sk", - " │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.household_demographics.hd_income_band_sk, tpcds.income_band.ib_income_band_sk)]", - " │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.household_demographics.hd_income_band_sk, collate: binary]", - " │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.income_band.ib_income_band_sk", - " │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.household_demographics.hd_income_band_sk, tpcds.income_band.ib_income_band_sk)]", - " │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.household_demographics.hd_income_band_sk, collate: binary]", - " │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_address_sk", - " │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.customer.c_current_addr_sk, tpcds.customer_address.ca_address_sk)]", - " │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer.c_current_addr_sk, collate: binary]", - " │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_addr_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_address_sk", - " │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_addr_sk, tpcds.customer_address.ca_address_sk)]", - " │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_addr_sk, collate: binary]", - " │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_addr_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.promotion.p_promo_sk", - " │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_promo_sk, tpcds.promotion.p_promo_sk)]", - " │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_promo_sk, collate: binary]", - " │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_addr_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.date_dim.d_date_sk", - " │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.customer.c_first_shipto_date_sk, tpcds.date_dim.d_date_sk)]", - " │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer.c_first_shipto_date_sk, collate: binary]", - " │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.date_dim.d_year, tpcds.date_dim.d_date_sk", - " │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.customer.c_first_sales_date_sk, tpcds.date_dim.d_date_sk)]", - " │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer.c_first_sales_date_sk, collate: binary]", - " │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.store_returns.sr_item_sk, tpcds.store_returns.sr_ticket_number", - " │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_item_sk, tpcds.store_returns.sr_item_sk) eq(tpcds.store_sales.ss_ticket_number, tpcds.store_returns.sr_ticket_number)]", - " │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_item_sk, collate: binary], [name: tpcds.store_sales.ss_ticket_number, collate: binary]", - " │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_demo_sk", - " │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.customer.c_current_hdemo_sk, tpcds.household_demographics.hd_demo_sk)]", - " │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer.c_current_hdemo_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_hdemo_sk, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_demo_sk", - " │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_hdemo_sk, tpcds.household_demographics.hd_demo_sk)]", - " │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_hdemo_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_hdemo_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_hdemo_sk, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.customer_demographics.cd_demo_sk", - " │ │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.customer.c_current_cdemo_sk, tpcds.customer_demographics.cd_demo_sk)], other cond:ne(tpcds.customer_demographics.cd_marital_status, tpcds.customer_demographics.cd_marital_status)", - " │ │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer.c_current_cdemo_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_hdemo_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_cdemo_sk, tpcds.customer.c_current_hdemo_sk, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.customer_demographics.cd_marital_status, tpcds.customer_demographics.cd_demo_sk", - " │ │ │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_cdemo_sk, tpcds.customer_demographics.cd_demo_sk)]", - " │ │ │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_cdemo_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_cdemo_sk, tpcds.store_sales.ss_hdemo_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_cdemo_sk, tpcds.customer.c_current_hdemo_sk, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.store.s_store_sk", - " │ │ │ │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_store_sk, tpcds.store.s_store_sk)]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_store_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_cdemo_sk, tpcds.store_sales.ss_hdemo_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_store_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_cdemo_sk, tpcds.customer.c_current_hdemo_sk, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.customer.c_customer_sk", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_customer_sk, tpcds.customer.c_customer_sk)]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_customer_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_customer_sk, tpcds.store_sales.ss_cdemo_sk, tpcds.store_sales.ss_hdemo_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_store_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.date_dim.d_date_sk", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_sold_date_sk, tpcds.date_dim.d_date_sk)]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_sold_date_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk)]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.item.i_item_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] ge(tpcds.item.i_current_price, 35), ge(tpcds.item.i_current_price, 36), le(tpcds.item.i_current_price, 45), le(tpcds.item.i_current_price, 50)", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:item pushed down filter:in(tpcds.item.i_color, \"maroon\", \"burnished\", \"dim\", \"steel\", \"navajo\", \"chocolate\"), keep order:false, stats:pseudo", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_item_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.store_sales.ss_addr_sk)), not(isnull(tpcds.store_sales.ss_cdemo_sk)), not(isnull(tpcds.store_sales.ss_customer_sk)), not(isnull(tpcds.store_sales.ss_hdemo_sk)), not(isnull(tpcds.store_sales.ss_promo_sk)), not(isnull(tpcds.store_sales.ss_sold_date_sk)), not(isnull(tpcds.store_sales.ss_store_sk))", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:store_sales keep order:false, stats:pseudo", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.date_dim.d_date_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:d1 pushed down filter:or(eq(tpcds.date_dim.d_year, 2000), eq(tpcds.date_dim.d_year, 2001)), keep order:false, stats:pseudo", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer.c_customer_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.customer.c_current_addr_sk)), not(isnull(tpcds.customer.c_current_cdemo_sk)), not(isnull(tpcds.customer.c_current_hdemo_sk)), not(isnull(tpcds.customer.c_first_sales_date_sk)), not(isnull(tpcds.customer.c_first_shipto_date_sk))", - " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:customer keep order:false, stats:pseudo", - " │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store.s_store_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.store.s_store_name)), not(isnull(tpcds.store.s_zip))", - " │ │ │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:store keep order:false, stats:pseudo", - " │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer_demographics.cd_demo_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.customer_demographics.cd_marital_status))", - " │ │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:cd1 keep order:false, stats:pseudo", - " │ │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer_demographics.cd_demo_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.customer_demographics.cd_marital_status))", - " │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:cd2 keep order:false, stats:pseudo", - " │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.household_demographics.hd_demo_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.household_demographics.hd_income_band_sk))", - " │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:hd1 keep order:false, stats:pseudo", - " │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.household_demographics.hd_demo_sk, collate: binary]", - " │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.household_demographics.hd_income_band_sk))", - " │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:hd2 keep order:false, stats:pseudo", - " │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_returns.sr_item_sk, collate: binary], [name: tpcds.store_returns.sr_ticket_number, collate: binary]", - " │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:store_returns keep order:false, stats:pseudo", - " │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.date_dim.d_date_sk, collate: binary]", - " │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:d2 keep order:false, stats:pseudo", - " │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.date_dim.d_date_sk, collate: binary]", - " │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:d3 keep order:false, stats:pseudo", - " │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.promotion.p_promo_sk, collate: binary]", - " │ │ │ │ │ └─TableFullScan mpp[tiflash] table:promotion keep order:false, stats:pseudo", - " │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer_address.ca_address_sk, collate: binary]", - " │ │ │ │ └─TableFullScan mpp[tiflash] table:ad1 keep order:false, stats:pseudo", - " │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer_address.ca_address_sk, collate: binary]", - " │ │ │ └─TableFullScan mpp[tiflash] table:ad2 keep order:false, stats:pseudo", - " │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.income_band.ib_income_band_sk, collate: binary]", - " │ │ └─TableFullScan mpp[tiflash] table:ib1 keep order:false, stats:pseudo", - " │ └─ExchangeReceiver(Probe) mpp[tiflash] ", - " │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.income_band.ib_income_band_sk, collate: binary]", - " │ └─TableFullScan mpp[tiflash] table:ib2 keep order:false, stats:pseudo", + " ├─Projection(Build) mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.store_returns.sr_item_sk", + " │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_item_sk, tpcds.store_returns.sr_item_sk) eq(tpcds.store_sales.ss_ticket_number, tpcds.store_returns.sr_ticket_number)]", + " │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_item_sk, collate: binary]", + " │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.income_band.ib_income_band_sk", + " │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.household_demographics.hd_income_band_sk, tpcds.income_band.ib_income_band_sk)]", + " │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.household_demographics.hd_income_band_sk, collate: binary]", + " │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.income_band.ib_income_band_sk", + " │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.household_demographics.hd_income_band_sk, tpcds.income_band.ib_income_band_sk)]", + " │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.household_demographics.hd_income_band_sk, collate: binary]", + " │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_address_sk", + " │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.customer.c_current_addr_sk, tpcds.customer_address.ca_address_sk)]", + " │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer.c_current_addr_sk, collate: binary]", + " │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_addr_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.customer_address.ca_street_number, tpcds.customer_address.ca_street_name, tpcds.customer_address.ca_city, tpcds.customer_address.ca_zip, tpcds.customer_address.ca_address_sk", + " │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_addr_sk, tpcds.customer_address.ca_address_sk)]", + " │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_addr_sk, collate: binary]", + " │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_addr_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.promotion.p_promo_sk", + " │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_promo_sk, tpcds.promotion.p_promo_sk)]", + " │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_promo_sk, collate: binary]", + " │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_addr_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.date_dim.d_year, tpcds.date_dim.d_year, tpcds.date_dim.d_date_sk", + " │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.customer.c_first_sales_date_sk, tpcds.date_dim.d_date_sk)]", + " │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer.c_first_sales_date_sk, collate: binary]", + " │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_sales_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.date_dim.d_year, tpcds.date_dim.d_date_sk", + " │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.customer.c_first_shipto_date_sk, tpcds.date_dim.d_date_sk)]", + " │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer.c_first_shipto_date_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_demo_sk", + " │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_hdemo_sk, tpcds.household_demographics.hd_demo_sk)]", + " │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_hdemo_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_hdemo_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.customer_demographics.cd_demo_sk", + " │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.customer.c_current_cdemo_sk, tpcds.customer_demographics.cd_demo_sk)], other cond:ne(tpcds.customer_demographics.cd_marital_status, tpcds.customer_demographics.cd_marital_status)", + " │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer.c_current_cdemo_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_hdemo_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_cdemo_sk, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.customer_demographics.cd_marital_status, tpcds.customer_demographics.cd_demo_sk", + " │ │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_cdemo_sk, tpcds.customer_demographics.cd_demo_sk)]", + " │ │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_cdemo_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_cdemo_sk, tpcds.store_sales.ss_hdemo_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_cdemo_sk, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.household_demographics.hd_income_band_sk, tpcds.household_demographics.hd_demo_sk", + " │ │ │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.customer.c_current_hdemo_sk, tpcds.household_demographics.hd_demo_sk)]", + " │ │ │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer.c_current_hdemo_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_cdemo_sk, tpcds.store_sales.ss_hdemo_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_cdemo_sk, tpcds.customer.c_current_hdemo_sk, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.store.s_store_name, tpcds.store.s_zip, tpcds.store.s_store_sk", + " │ │ │ │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_store_sk, tpcds.store.s_store_sk)]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_store_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_cdemo_sk, tpcds.store_sales.ss_hdemo_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_store_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.customer.c_current_cdemo_sk, tpcds.customer.c_current_hdemo_sk, tpcds.customer.c_current_addr_sk, tpcds.customer.c_first_shipto_date_sk, tpcds.customer.c_first_sales_date_sk, tpcds.customer.c_customer_sk", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_customer_sk, tpcds.customer.c_customer_sk)]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_customer_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk, tpcds.store_sales.ss_customer_sk, tpcds.store_sales.ss_cdemo_sk, tpcds.store_sales.ss_hdemo_sk, tpcds.store_sales.ss_addr_sk, tpcds.store_sales.ss_store_sk, tpcds.store_sales.ss_promo_sk, tpcds.store_sales.ss_ticket_number, tpcds.store_sales.ss_wholesale_cost, tpcds.store_sales.ss_list_price, tpcds.store_sales.ss_coupon_amt, tpcds.date_dim.d_year, tpcds.date_dim.d_date_sk", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.store_sales.ss_sold_date_sk, tpcds.date_dim.d_date_sk)]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_sold_date_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─HashJoin mpp[tiflash] inner join, equal:[eq(tpcds.item.i_item_sk, tpcds.store_sales.ss_item_sk)]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─ExchangeReceiver(Build) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.item.i_item_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─Projection mpp[tiflash] tpcds.item.i_item_sk, tpcds.item.i_product_name, tpcds.item.i_item_sk", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] ge(tpcds.item.i_current_price, 35), ge(tpcds.item.i_current_price, 36), le(tpcds.item.i_current_price, 45), le(tpcds.item.i_current_price, 50)", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:item pushed down filter:in(tpcds.item.i_color, \"maroon\", \"burnished\", \"dim\", \"steel\", \"navajo\", \"chocolate\"), keep order:false, stats:pseudo", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_sales.ss_item_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.store_sales.ss_addr_sk)), not(isnull(tpcds.store_sales.ss_cdemo_sk)), not(isnull(tpcds.store_sales.ss_customer_sk)), not(isnull(tpcds.store_sales.ss_hdemo_sk)), not(isnull(tpcds.store_sales.ss_promo_sk)), not(isnull(tpcds.store_sales.ss_sold_date_sk)), not(isnull(tpcds.store_sales.ss_store_sk))", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:store_sales keep order:false, stats:pseudo", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.date_dim.d_date_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:d1 pushed down filter:or(eq(tpcds.date_dim.d_year, 2000), eq(tpcds.date_dim.d_year, 2001)), keep order:false, stats:pseudo", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer.c_customer_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.customer.c_current_addr_sk)), not(isnull(tpcds.customer.c_current_cdemo_sk)), not(isnull(tpcds.customer.c_current_hdemo_sk)), not(isnull(tpcds.customer.c_first_sales_date_sk)), not(isnull(tpcds.customer.c_first_shipto_date_sk))", + " │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:customer keep order:false, stats:pseudo", + " │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store.s_store_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.store.s_store_name)), not(isnull(tpcds.store.s_zip))", + " │ │ │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:store keep order:false, stats:pseudo", + " │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.household_demographics.hd_demo_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.household_demographics.hd_income_band_sk))", + " │ │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:hd2 keep order:false, stats:pseudo", + " │ │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer_demographics.cd_demo_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.customer_demographics.cd_marital_status))", + " │ │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:cd1 keep order:false, stats:pseudo", + " │ │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer_demographics.cd_demo_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.customer_demographics.cd_marital_status))", + " │ │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:cd2 keep order:false, stats:pseudo", + " │ │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.household_demographics.hd_demo_sk, collate: binary]", + " │ │ │ │ │ │ │ │ │ └─Selection mpp[tiflash] not(isnull(tpcds.household_demographics.hd_income_band_sk))", + " │ │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:hd1 keep order:false, stats:pseudo", + " │ │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.date_dim.d_date_sk, collate: binary]", + " │ │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:d3 keep order:false, stats:pseudo", + " │ │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.date_dim.d_date_sk, collate: binary]", + " │ │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:d2 keep order:false, stats:pseudo", + " │ │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.promotion.p_promo_sk, collate: binary]", + " │ │ │ │ │ │ └─TableFullScan mpp[tiflash] table:promotion keep order:false, stats:pseudo", + " │ │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer_address.ca_address_sk, collate: binary]", + " │ │ │ │ │ └─TableFullScan mpp[tiflash] table:ad1 keep order:false, stats:pseudo", + " │ │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.customer_address.ca_address_sk, collate: binary]", + " │ │ │ │ └─TableFullScan mpp[tiflash] table:ad2 keep order:false, stats:pseudo", + " │ │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.income_band.ib_income_band_sk, collate: binary]", + " │ │ │ └─TableFullScan mpp[tiflash] table:ib1 keep order:false, stats:pseudo", + " │ │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.income_band.ib_income_band_sk, collate: binary]", + " │ │ └─TableFullScan mpp[tiflash] table:ib2 keep order:false, stats:pseudo", + " │ └─ExchangeReceiver(Probe) mpp[tiflash] ", + " │ └─ExchangeSender mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: tpcds.store_returns.sr_item_sk, collate: binary]", + " │ └─TableFullScan mpp[tiflash] table:store_returns keep order:false, stats:pseudo", " └─Selection(Probe) mpp[tiflash] gt(Column, mul(2, Column))", " └─Projection mpp[tiflash] Column, Column, tpcds.catalog_sales.cs_item_sk", " └─HashAgg mpp[tiflash] group by:Column, funcs:sum(Column)->Column, funcs:sum(Column)->Column, funcs:firstrow(Column)->tpcds.catalog_sales.cs_item_sk", diff --git a/pkg/planner/core/casetest/tpch/testdata/tpch_suite_out.json b/pkg/planner/core/casetest/tpch/testdata/tpch_suite_out.json index d88eae910cbd6..9bb4710d32fa8 100644 --- a/pkg/planner/core/casetest/tpch/testdata/tpch_suite_out.json +++ b/pkg/planner/core/casetest/tpch/testdata/tpch_suite_out.json @@ -26,68 +26,68 @@ { "SQL": "SELECT s_acctbal, s_name, n_name, p_partkey, p_mfgr, s_address, s_phone, s_comment FROM part, supplier, partsupp, nation, region WHERE p_partkey = ps_partkey AND s_suppkey = ps_suppkey AND p_size = 30 AND p_type LIKE '%STEEL' AND s_nationkey = n_nationkey AND n_regionkey = r_regionkey AND r_name = 'ASIA' AND ps_supplycost = (SELECT MIN(ps_supplycost) FROM partsupp, supplier, nation, region WHERE p_partkey = ps_partkey AND s_suppkey = ps_suppkey AND s_nationkey = n_nationkey AND n_regionkey = r_regionkey AND r_name = 'ASIA') ORDER BY s_acctbal DESC, n_name, s_name, p_partkey LIMIT 100;", "Result": [ - "Projection_39 100.00 922571773.52 (((((((((((((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(158044.3476975649*filters(0.08)*tiflash_cpu_factor(2.4)))/5.00)) + ((exprCPU(158044.3476975649*0*tiflash_cpu_factor(2.4))) + (orderCPU(158044.3476975649*log(100)*tiflash_cpu_factor(2.4)))) + (topMem(100*240*tiflash_mem_factor(0.05))))*1.00)) + (net(100*rowsize(240)*tidb_flash_net_factor(2.2))))/15.00)*1.00) + ((exprCPU(100*0*tidb_cpu_factor(49.9))) + (orderCPU(100*log(100)*tidb_cpu_factor(49.9)))) + (topMem(100*240*tidb_mem_factor(0.2))))*1.00) + ((cpu(100*filters(0.08)*tidb_cpu_factor(49.9)))/5.00) root test.supplier.s_acctbal, test.supplier.s_name, test.nation.n_name, test.part.p_partkey, test.part.p_mfgr, test.supplier.s_address, test.supplier.s_phone, test.supplier.s_comment", - "└─TopN_44 100.00 922571693.68 ((((((((((((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(158044.3476975649*filters(0.08)*tiflash_cpu_factor(2.4)))/5.00)) + ((exprCPU(158044.3476975649*0*tiflash_cpu_factor(2.4))) + (orderCPU(158044.3476975649*log(100)*tiflash_cpu_factor(2.4)))) + (topMem(100*240*tiflash_mem_factor(0.05))))*1.00)) + (net(100*rowsize(240)*tidb_flash_net_factor(2.2))))/15.00)*1.00) + ((exprCPU(100*0*tidb_cpu_factor(49.9))) + (orderCPU(100*log(100)*tidb_cpu_factor(49.9)))) + (topMem(100*240*tidb_mem_factor(0.2))))*1.00 root test.supplier.s_acctbal:desc, test.nation.n_name, test.supplier.s_name, test.part.p_partkey, offset:0, count:100", - " └─TableReader_382 100.00 922533740.84 ((((((((((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(158044.3476975649*filters(0.08)*tiflash_cpu_factor(2.4)))/5.00)) + ((exprCPU(158044.3476975649*0*tiflash_cpu_factor(2.4))) + (orderCPU(158044.3476975649*log(100)*tiflash_cpu_factor(2.4)))) + (topMem(100*240*tiflash_mem_factor(0.05))))*1.00)) + (net(100*rowsize(240)*tidb_flash_net_factor(2.2))))/15.00)*1.00 root MppVersion: 3, data:ExchangeSender_381", - " └─ExchangeSender_381 100.00 13837953312.55 (((((((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(158044.3476975649*filters(0.08)*tiflash_cpu_factor(2.4)))/5.00)) + ((exprCPU(158044.3476975649*0*tiflash_cpu_factor(2.4))) + (orderCPU(158044.3476975649*log(100)*tiflash_cpu_factor(2.4)))) + (topMem(100*240*tiflash_mem_factor(0.05))))*1.00) mpp[tiflash] ExchangeType: PassThrough", - " └─TopN_380 100.00 13837953312.55 ((((((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(158044.3476975649*filters(0.08)*tiflash_cpu_factor(2.4)))/5.00)) + ((exprCPU(158044.3476975649*0*tiflash_cpu_factor(2.4))) + (orderCPU(158044.3476975649*log(100)*tiflash_cpu_factor(2.4)))) + (topMem(100*240*tiflash_mem_factor(0.05))))*1.00 mpp[tiflash] test.supplier.s_acctbal:desc, test.nation.n_name, test.supplier.s_name, test.part.p_partkey, offset:0, count:100", - " └─Projection_379 158044.35 13835432055.15 ((((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(158044.3476975649*filters(0.08)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.part.p_partkey, test.part.p_mfgr, test.supplier.s_name, test.supplier.s_address, test.supplier.s_phone, test.supplier.s_acctbal, test.supplier.s_comment, test.nation.n_name", - " └─Projection_376 158044.35 13835425986.24 (((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.nation.n_name, test.supplier.s_name, test.supplier.s_address, test.supplier.s_phone, test.supplier.s_acctbal, test.supplier.s_comment, test.part.p_partkey, test.part.p_mfgr, test.partsupp.ps_partkey, Column#59", - " └─HashJoin_375 158044.35 13835418400.11 ((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.part.p_partkey, test.partsupp.ps_partkey) eq(test.partsupp.ps_supplycost, Column#59)]", - " ├─ExchangeReceiver_91(Build) 158044.35 6848670154.37 ((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", - " │ └─ExchangeSender_90 158044.35 6803153382.24 (((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.part.p_partkey, collate: binary], [name: test.partsupp.ps_supplycost, collate: binary]", - " │ └─Projection_89 158044.35 6803153382.24 ((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.nation.n_name, test.supplier.s_name, test.supplier.s_address, test.supplier.s_phone, test.supplier.s_acctbal, test.supplier.s_comment, test.partsupp.ps_supplycost, test.part.p_partkey, test.part.p_mfgr, test.partsupp.ps_suppkey", - " │ └─HashJoin_65 158044.35 6803145796.11 (((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.partsupp.ps_partkey, test.part.p_partkey)]", - " │ ├─ExchangeReceiver_88(Build) 158044.35 521421689.50 (((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00) mpp[tiflash] ", - " │ │ └─ExchangeSender_87 158044.35 485264303.64 ((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00)) mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ │ └─Selection_86 158044.35 485264303.64 (cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00) mpp[tiflash] like(test.part.p_type, \"%STEEL\", 92)", - " │ │ └─TableFullScan_85 197555.43 484790170.59 ((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00 mpp[tiflash] table:part pushed down filter:eq(test.part.p_size, 30), keep order:false", - " │ └─Projection_84(Probe) 8021852.14 6268435397.86 ((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.nation.n_name, test.supplier.s_name, test.supplier.s_address, test.supplier.s_phone, test.supplier.s_acctbal, test.supplier.s_comment, test.partsupp.ps_partkey, test.partsupp.ps_supplycost, test.partsupp.ps_suppkey", - " │ └─HashJoin_66 8021852.14 6268088853.85 (((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.supplier.s_suppkey, test.partsupp.ps_suppkey)]", - " │ ├─ExchangeReceiver_80(Build) 99997.20 69462555.35 (((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", - " │ │ └─ExchangeSender_79 99997.20 47963157.35 ((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.supplier.s_suppkey, collate: binary]", - " │ │ └─Projection_78 99997.20 47963157.35 (((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.nation.n_name, test.supplier.s_suppkey, test.supplier.s_name, test.supplier.s_address, test.supplier.s_phone, test.supplier.s_acctbal, test.supplier.s_comment", - " │ │ └─HashJoin_67 99997.20 47959797.44 ((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.nation.n_nationkey, test.supplier.s_nationkey)]", - " │ │ ├─ExchangeReceiver_76(Build) 5.00 1202425.23 ((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00) mpp[tiflash] ", - " │ │ │ └─ExchangeSender_75 5.00 1201930.23 (((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ │ │ └─Projection_74 5.00 1201930.23 ((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.nation.n_nationkey, test.nation.n_name", - " │ │ │ └─HashJoin_68 5.00 1201930.19 (((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.region.r_regionkey, test.nation.n_regionkey)]", - " │ │ │ ├─ExchangeReceiver_72(Build) 1.00 562979.73 (((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00) mpp[tiflash] ", - " │ │ │ │ └─ExchangeSender_71 1.00 562893.21 ((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00)) mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ │ │ │ └─Selection_70 1.00 562893.21 (cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00) mpp[tiflash] eq(test.region.r_name, \"ASIA\")", - " │ │ │ │ └─TableFullScan_69 5.00 562881.21 ((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:region keep order:false", - " │ │ │ └─TableFullScan_73(Probe) 25.00 638908.37 ((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:nation keep order:false", - " │ │ └─TableFullScan_77(Probe) 500000.00 45957361.46 ((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:supplier keep order:false", - " │ └─ExchangeReceiver_83(Probe) 40000000.00 6134107979.69 ((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", - " │ └─ExchangeSender_82 40000000.00 2934107979.69 (((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.partsupp.ps_suppkey, collate: binary]", - " │ └─TableFullScan_81 40000000.00 2934107979.69 ((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:partsupp keep order:false", - " └─ExchangeReceiver_126(Probe) 6417481.71 6970208370.33 (((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", - " └─ExchangeSender_125 6417481.71 6662169248.27 ((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.partsupp.ps_partkey, collate: binary], [name: Column#59, collate: binary]", - " └─Selection_93 6417481.71 6662169248.27 (cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] not(isnull(Column#59))", - " └─Projection_119 8021852.14 6642916803.14 (((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] Column#59, test.partsupp.ps_partkey", - " └─HashAgg_94 8021852.14 6642839793.36 ((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00 mpp[tiflash] group by:test.partsupp.ps_partkey, funcs:min(test.partsupp.ps_supplycost)->Column#59, funcs:firstrow(test.partsupp.ps_partkey)->test.partsupp.ps_partkey", - " └─ExchangeReceiver_118 8021852.14 6615847793.29 (((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", - " └─ExchangeSender_117 8021852.14 6230798890.71 ((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.partsupp.ps_partkey, collate: binary]", - " └─Projection_97 8021852.14 6230798890.71 (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.partsupp.ps_partkey, test.partsupp.ps_supplycost", - " └─Projection_116 8021852.14 6230721880.93 ((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.partsupp.ps_partkey, test.partsupp.ps_supplycost, test.partsupp.ps_suppkey", - " └─HashJoin_98 8021852.14 6230606366.26 (((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.supplier.s_suppkey, test.partsupp.ps_suppkey)]", - " ├─ExchangeReceiver_112(Build) 99997.20 32325058.09 (((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", - " │ └─ExchangeSender_111 99997.20 31525080.49 ((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.supplier.s_suppkey, collate: binary]", - " │ └─Projection_110 99997.20 31525080.49 (((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.supplier.s_suppkey", - " │ └─HashJoin_99 99997.20 31524600.51 ((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.nation.n_nationkey, test.supplier.s_nationkey)]", - " │ ├─ExchangeReceiver_108(Build) 5.00 1144591.84 ((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00) mpp[tiflash] ", - " │ │ └─ExchangeSender_107 5.00 1144471.84 (((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ │ └─Projection_106 5.00 1144471.84 ((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.nation.n_nationkey", - " │ │ └─HashJoin_100 5.00 1144471.81 (((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.region.r_regionkey, test.nation.n_regionkey)]", - " │ │ ├─ExchangeReceiver_104(Build) 1.00 562979.73 (((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00) mpp[tiflash] ", - " │ │ │ └─ExchangeSender_103 1.00 562893.21 ((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00)) mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ │ │ └─Selection_102 1.00 562893.21 (cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00) mpp[tiflash] eq(test.region.r_name, \"ASIA\")", - " │ │ │ └─TableFullScan_101 5.00 562881.21 ((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:region keep order:false", - " │ │ └─TableFullScan_105(Probe) 25.00 581450.00 ((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:nation keep order:false", - " │ └─TableFullScan_109(Probe) 500000.00 29580000.00 ((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:supplier keep order:false", - " └─ExchangeReceiver_115(Probe) 40000000.00 6134107979.69 ((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", - " └─ExchangeSender_114 40000000.00 2934107979.69 (((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.partsupp.ps_suppkey, collate: binary]", - " └─TableFullScan_113 40000000.00 2934107979.69 ((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:partsupp keep order:false" + "Projection_40 100.00 922571773.52 (((((((((((((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(158044.3476975649*filters(0.08)*tiflash_cpu_factor(2.4)))/5.00)) + ((exprCPU(158044.3476975649*0*tiflash_cpu_factor(2.4))) + (orderCPU(158044.3476975649*log(100)*tiflash_cpu_factor(2.4)))) + (topMem(100*240*tiflash_mem_factor(0.05))))*1.00)) + (net(100*rowsize(240)*tidb_flash_net_factor(2.2))))/15.00)*1.00) + ((exprCPU(100*0*tidb_cpu_factor(49.9))) + (orderCPU(100*log(100)*tidb_cpu_factor(49.9)))) + (topMem(100*240*tidb_mem_factor(0.2))))*1.00) + ((cpu(100*filters(0.08)*tidb_cpu_factor(49.9)))/5.00) root test.supplier.s_acctbal, test.supplier.s_name, test.nation.n_name, test.part.p_partkey, test.part.p_mfgr, test.supplier.s_address, test.supplier.s_phone, test.supplier.s_comment", + "└─TopN_45 100.00 922571693.68 ((((((((((((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(158044.3476975649*filters(0.08)*tiflash_cpu_factor(2.4)))/5.00)) + ((exprCPU(158044.3476975649*0*tiflash_cpu_factor(2.4))) + (orderCPU(158044.3476975649*log(100)*tiflash_cpu_factor(2.4)))) + (topMem(100*240*tiflash_mem_factor(0.05))))*1.00)) + (net(100*rowsize(240)*tidb_flash_net_factor(2.2))))/15.00)*1.00) + ((exprCPU(100*0*tidb_cpu_factor(49.9))) + (orderCPU(100*log(100)*tidb_cpu_factor(49.9)))) + (topMem(100*240*tidb_mem_factor(0.2))))*1.00 root test.supplier.s_acctbal:desc, test.nation.n_name, test.supplier.s_name, test.part.p_partkey, offset:0, count:100", + " └─TableReader_383 100.00 922533740.84 ((((((((((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(158044.3476975649*filters(0.08)*tiflash_cpu_factor(2.4)))/5.00)) + ((exprCPU(158044.3476975649*0*tiflash_cpu_factor(2.4))) + (orderCPU(158044.3476975649*log(100)*tiflash_cpu_factor(2.4)))) + (topMem(100*240*tiflash_mem_factor(0.05))))*1.00)) + (net(100*rowsize(240)*tidb_flash_net_factor(2.2))))/15.00)*1.00 root MppVersion: 3, data:ExchangeSender_382", + " └─ExchangeSender_382 100.00 13837953312.55 (((((((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(158044.3476975649*filters(0.08)*tiflash_cpu_factor(2.4)))/5.00)) + ((exprCPU(158044.3476975649*0*tiflash_cpu_factor(2.4))) + (orderCPU(158044.3476975649*log(100)*tiflash_cpu_factor(2.4)))) + (topMem(100*240*tiflash_mem_factor(0.05))))*1.00) mpp[tiflash] ExchangeType: PassThrough", + " └─TopN_381 100.00 13837953312.55 ((((((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(158044.3476975649*filters(0.08)*tiflash_cpu_factor(2.4)))/5.00)) + ((exprCPU(158044.3476975649*0*tiflash_cpu_factor(2.4))) + (orderCPU(158044.3476975649*log(100)*tiflash_cpu_factor(2.4)))) + (topMem(100*240*tiflash_mem_factor(0.05))))*1.00 mpp[tiflash] test.supplier.s_acctbal:desc, test.nation.n_name, test.supplier.s_name, test.part.p_partkey, offset:0, count:100", + " └─Projection_380 158044.35 13835432055.15 ((((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(158044.3476975649*filters(0.08)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.part.p_partkey, test.part.p_mfgr, test.supplier.s_name, test.supplier.s_address, test.supplier.s_phone, test.supplier.s_acctbal, test.supplier.s_comment, test.nation.n_name", + " └─Projection_377 158044.35 13835425986.24 (((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.nation.n_name, test.supplier.s_name, test.supplier.s_address, test.supplier.s_phone, test.supplier.s_acctbal, test.supplier.s_comment, test.part.p_partkey, test.part.p_mfgr, test.partsupp.ps_partkey, Column#59", + " └─HashJoin_376 158044.35 13835418400.11 ((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.part.p_partkey, test.partsupp.ps_partkey) eq(test.partsupp.ps_supplycost, Column#59)]", + " ├─ExchangeReceiver_92(Build) 158044.35 6848670154.37 ((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", + " │ └─ExchangeSender_91 158044.35 6803153382.24 (((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.part.p_partkey, collate: binary], [name: test.partsupp.ps_supplycost, collate: binary]", + " │ └─Projection_90 158044.35 6803153382.24 ((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.nation.n_name, test.supplier.s_name, test.supplier.s_address, test.supplier.s_phone, test.supplier.s_acctbal, test.supplier.s_comment, test.partsupp.ps_supplycost, test.part.p_partkey, test.part.p_mfgr, test.partsupp.ps_suppkey", + " │ └─HashJoin_66 158044.35 6803145796.11 (((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.partsupp.ps_partkey, test.part.p_partkey)]", + " │ ├─ExchangeReceiver_89(Build) 158044.35 521421689.50 (((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00) mpp[tiflash] ", + " │ │ └─ExchangeSender_88 158044.35 485264303.64 ((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00)) mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ │ └─Selection_87 158044.35 485264303.64 (cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00) mpp[tiflash] like(test.part.p_type, \"%STEEL\", 92)", + " │ │ └─TableFullScan_86 197555.43 484790170.59 ((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00 mpp[tiflash] table:part pushed down filter:eq(test.part.p_size, 30), keep order:false", + " │ └─Projection_85(Probe) 8021852.14 6268435397.86 ((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.nation.n_name, test.supplier.s_name, test.supplier.s_address, test.supplier.s_phone, test.supplier.s_acctbal, test.supplier.s_comment, test.partsupp.ps_partkey, test.partsupp.ps_supplycost, test.partsupp.ps_suppkey", + " │ └─HashJoin_67 8021852.14 6268088853.85 (((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.supplier.s_suppkey, test.partsupp.ps_suppkey)]", + " │ ├─ExchangeReceiver_81(Build) 99997.20 69462555.35 (((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", + " │ │ └─ExchangeSender_80 99997.20 47963157.35 ((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.supplier.s_suppkey, collate: binary]", + " │ │ └─Projection_79 99997.20 47963157.35 (((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.nation.n_name, test.supplier.s_suppkey, test.supplier.s_name, test.supplier.s_address, test.supplier.s_phone, test.supplier.s_acctbal, test.supplier.s_comment", + " │ │ └─HashJoin_68 99997.20 47959797.44 ((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.nation.n_nationkey, test.supplier.s_nationkey)]", + " │ │ ├─ExchangeReceiver_77(Build) 5.00 1202425.23 ((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00) mpp[tiflash] ", + " │ │ │ └─ExchangeSender_76 5.00 1201930.23 (((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ │ │ └─Projection_75 5.00 1201930.23 ((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.nation.n_nationkey, test.nation.n_name", + " │ │ │ └─HashJoin_69 5.00 1201930.19 (((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.region.r_regionkey, test.nation.n_regionkey)]", + " │ │ │ ├─ExchangeReceiver_73(Build) 1.00 562979.73 (((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00) mpp[tiflash] ", + " │ │ │ │ └─ExchangeSender_72 1.00 562893.21 ((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00)) mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ │ │ │ └─Selection_71 1.00 562893.21 (cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00) mpp[tiflash] eq(test.region.r_name, \"ASIA\")", + " │ │ │ │ └─TableFullScan_70 5.00 562881.21 ((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:region keep order:false", + " │ │ │ └─TableFullScan_74(Probe) 25.00 638908.37 ((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:nation keep order:false", + " │ │ └─TableFullScan_78(Probe) 500000.00 45957361.46 ((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:supplier keep order:false", + " │ └─ExchangeReceiver_84(Probe) 40000000.00 6134107979.69 ((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", + " │ └─ExchangeSender_83 40000000.00 2934107979.69 (((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.partsupp.ps_suppkey, collate: binary]", + " │ └─TableFullScan_82 40000000.00 2934107979.69 ((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:partsupp keep order:false", + " └─ExchangeReceiver_127(Probe) 6417481.71 6970208370.33 (((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", + " └─ExchangeSender_126 6417481.71 6662169248.27 ((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.partsupp.ps_partkey, collate: binary], [name: Column#59, collate: binary]", + " └─Selection_94 6417481.71 6662169248.27 (cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] not(isnull(Column#59))", + " └─Projection_120 8021852.14 6642916803.14 (((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] Column#59, test.partsupp.ps_partkey", + " └─HashAgg_95 8021852.14 6642839793.36 ((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00 mpp[tiflash] group by:test.partsupp.ps_partkey, funcs:min(test.partsupp.ps_supplycost)->Column#59, funcs:firstrow(test.partsupp.ps_partkey)->test.partsupp.ps_partkey", + " └─ExchangeReceiver_119 8021852.14 6615847793.29 (((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", + " └─ExchangeSender_118 8021852.14 6230798890.71 ((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.partsupp.ps_partkey, collate: binary]", + " └─Projection_98 8021852.14 6230798890.71 (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.partsupp.ps_partkey, test.partsupp.ps_supplycost", + " └─Projection_117 8021852.14 6230721880.93 ((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.partsupp.ps_partkey, test.partsupp.ps_supplycost, test.partsupp.ps_suppkey", + " └─HashJoin_99 8021852.14 6230606366.26 (((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.supplier.s_suppkey, test.partsupp.ps_suppkey)]", + " ├─ExchangeReceiver_113(Build) 99997.20 32325058.09 (((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", + " │ └─ExchangeSender_112 99997.20 31525080.49 ((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.supplier.s_suppkey, collate: binary]", + " │ └─Projection_111 99997.20 31525080.49 (((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.supplier.s_suppkey", + " │ └─HashJoin_100 99997.20 31524600.51 ((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.nation.n_nationkey, test.supplier.s_nationkey)]", + " │ ├─ExchangeReceiver_109(Build) 5.00 1144591.84 ((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00) mpp[tiflash] ", + " │ │ └─ExchangeSender_108 5.00 1144471.84 (((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ │ └─Projection_107 5.00 1144471.84 ((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.nation.n_nationkey", + " │ │ └─HashJoin_101 5.00 1144471.81 (((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.region.r_regionkey, test.nation.n_regionkey)]", + " │ │ ├─ExchangeReceiver_105(Build) 1.00 562979.73 (((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00) mpp[tiflash] ", + " │ │ │ └─ExchangeSender_104 1.00 562893.21 ((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00)) mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ │ │ └─Selection_103 1.00 562893.21 (cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00) mpp[tiflash] eq(test.region.r_name, \"ASIA\")", + " │ │ │ └─TableFullScan_102 5.00 562881.21 ((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:region keep order:false", + " │ │ └─TableFullScan_106(Probe) 25.00 581450.00 ((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:nation keep order:false", + " │ └─TableFullScan_110(Probe) 500000.00 29580000.00 ((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:supplier keep order:false", + " └─ExchangeReceiver_116(Probe) 40000000.00 6134107979.69 ((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", + " └─ExchangeSender_115 40000000.00 2934107979.69 (((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.partsupp.ps_suppkey, collate: binary]", + " └─TableFullScan_114 40000000.00 2934107979.69 ((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:partsupp keep order:false" ] } ] diff --git a/pkg/planner/core/casetest/tpch/testdata/tpch_suite_xut.json b/pkg/planner/core/casetest/tpch/testdata/tpch_suite_xut.json index 9de20d52068a4..38d924a12b71b 100644 --- a/pkg/planner/core/casetest/tpch/testdata/tpch_suite_xut.json +++ b/pkg/planner/core/casetest/tpch/testdata/tpch_suite_xut.json @@ -26,68 +26,68 @@ { "SQL": "SELECT s_acctbal, s_name, n_name, p_partkey, p_mfgr, s_address, s_phone, s_comment FROM part, supplier, partsupp, nation, region WHERE p_partkey = ps_partkey AND s_suppkey = ps_suppkey AND p_size = 30 AND p_type LIKE '%STEEL' AND s_nationkey = n_nationkey AND n_regionkey = r_regionkey AND r_name = 'ASIA' AND ps_supplycost = (SELECT MIN(ps_supplycost) FROM partsupp, supplier, nation, region WHERE p_partkey = ps_partkey AND s_suppkey = ps_suppkey AND s_nationkey = n_nationkey AND n_regionkey = r_regionkey AND r_name = 'ASIA') ORDER BY s_acctbal DESC, n_name, s_name, p_partkey LIMIT 100;", "Result": [ - "Projection_39 100.00 922571773.52 (((((((((((((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(158044.3476975649*filters(0.08)*tiflash_cpu_factor(2.4)))/5.00)) + ((exprCPU(158044.3476975649*0*tiflash_cpu_factor(2.4))) + (orderCPU(158044.3476975649*log(100)*tiflash_cpu_factor(2.4)))) + (topMem(100*240*tiflash_mem_factor(0.05))))*1.00)) + (net(100*rowsize(240)*tidb_flash_net_factor(2.2))))/15.00)*1.00) + ((exprCPU(100*0*tidb_cpu_factor(49.9))) + (orderCPU(100*log(100)*tidb_cpu_factor(49.9)))) + (topMem(100*240*tidb_mem_factor(0.2))))*1.00) + ((cpu(100*filters(0.08)*tidb_cpu_factor(49.9)))/5.00) root test.supplier.s_acctbal, test.supplier.s_name, test.nation.n_name, test.part.p_partkey, test.part.p_mfgr, test.supplier.s_address, test.supplier.s_phone, test.supplier.s_comment", - "└─TopN_44 100.00 922571693.68 ((((((((((((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(158044.3476975649*filters(0.08)*tiflash_cpu_factor(2.4)))/5.00)) + ((exprCPU(158044.3476975649*0*tiflash_cpu_factor(2.4))) + (orderCPU(158044.3476975649*log(100)*tiflash_cpu_factor(2.4)))) + (topMem(100*240*tiflash_mem_factor(0.05))))*1.00)) + (net(100*rowsize(240)*tidb_flash_net_factor(2.2))))/15.00)*1.00) + ((exprCPU(100*0*tidb_cpu_factor(49.9))) + (orderCPU(100*log(100)*tidb_cpu_factor(49.9)))) + (topMem(100*240*tidb_mem_factor(0.2))))*1.00 root test.supplier.s_acctbal:desc, test.nation.n_name, test.supplier.s_name, test.part.p_partkey, offset:0, count:100", - " └─TableReader_382 100.00 922533740.84 ((((((((((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(158044.3476975649*filters(0.08)*tiflash_cpu_factor(2.4)))/5.00)) + ((exprCPU(158044.3476975649*0*tiflash_cpu_factor(2.4))) + (orderCPU(158044.3476975649*log(100)*tiflash_cpu_factor(2.4)))) + (topMem(100*240*tiflash_mem_factor(0.05))))*1.00)) + (net(100*rowsize(240)*tidb_flash_net_factor(2.2))))/15.00)*1.00 root MppVersion: 3, data:ExchangeSender_381", - " └─ExchangeSender_381 100.00 13837953312.55 (((((((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(158044.3476975649*filters(0.08)*tiflash_cpu_factor(2.4)))/5.00)) + ((exprCPU(158044.3476975649*0*tiflash_cpu_factor(2.4))) + (orderCPU(158044.3476975649*log(100)*tiflash_cpu_factor(2.4)))) + (topMem(100*240*tiflash_mem_factor(0.05))))*1.00) mpp[tiflash] ExchangeType: PassThrough", - " └─TopN_380 100.00 13837953312.55 ((((((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(158044.3476975649*filters(0.08)*tiflash_cpu_factor(2.4)))/5.00)) + ((exprCPU(158044.3476975649*0*tiflash_cpu_factor(2.4))) + (orderCPU(158044.3476975649*log(100)*tiflash_cpu_factor(2.4)))) + (topMem(100*240*tiflash_mem_factor(0.05))))*1.00 mpp[tiflash] test.supplier.s_acctbal:desc, test.nation.n_name, test.supplier.s_name, test.part.p_partkey, offset:0, count:100", - " └─Projection_379 158044.35 13835432055.15 ((((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(158044.3476975649*filters(0.08)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.part.p_partkey, test.part.p_mfgr, test.supplier.s_name, test.supplier.s_address, test.supplier.s_phone, test.supplier.s_acctbal, test.supplier.s_comment, test.nation.n_name", - " └─Projection_376 158044.35 13835425986.24 (((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.nation.n_name, test.supplier.s_name, test.supplier.s_address, test.supplier.s_phone, test.supplier.s_acctbal, test.supplier.s_comment, test.part.p_partkey, test.part.p_mfgr, test.partsupp.ps_partkey, Column#59", - " └─HashJoin_375 158044.35 13835418400.11 ((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.part.p_partkey, test.partsupp.ps_partkey) eq(test.partsupp.ps_supplycost, Column#59)]", - " ├─ExchangeReceiver_91(Build) 158044.35 6848670154.37 ((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", - " │ └─ExchangeSender_90 158044.35 6803153382.24 (((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.part.p_partkey, collate: binary], [name: test.partsupp.ps_supplycost, collate: binary]", - " │ └─Projection_89 158044.35 6803153382.24 ((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.nation.n_name, test.supplier.s_name, test.supplier.s_address, test.supplier.s_phone, test.supplier.s_acctbal, test.supplier.s_comment, test.partsupp.ps_supplycost, test.part.p_partkey, test.part.p_mfgr, test.partsupp.ps_suppkey", - " │ └─HashJoin_65 158044.35 6803145796.11 (((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.partsupp.ps_partkey, test.part.p_partkey)]", - " │ ├─ExchangeReceiver_88(Build) 158044.35 521421689.50 (((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00) mpp[tiflash] ", - " │ │ └─ExchangeSender_87 158044.35 485264303.64 ((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00)) mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ │ └─Selection_86 158044.35 485264303.64 (cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00) mpp[tiflash] like(test.part.p_type, \"%STEEL\", 92)", - " │ │ └─TableFullScan_85 197555.43 484790170.59 ((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00 mpp[tiflash] table:part pushed down filter:eq(test.part.p_size, 30), keep order:false", - " │ └─Projection_84(Probe) 8021852.14 6268435397.86 ((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.nation.n_name, test.supplier.s_name, test.supplier.s_address, test.supplier.s_phone, test.supplier.s_acctbal, test.supplier.s_comment, test.partsupp.ps_partkey, test.partsupp.ps_supplycost, test.partsupp.ps_suppkey", - " │ └─HashJoin_66 8021852.14 6268088853.85 (((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.supplier.s_suppkey, test.partsupp.ps_suppkey)]", - " │ ├─ExchangeReceiver_80(Build) 99997.20 69462555.35 (((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", - " │ │ └─ExchangeSender_79 99997.20 47963157.35 ((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.supplier.s_suppkey, collate: binary]", - " │ │ └─Projection_78 99997.20 47963157.35 (((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.nation.n_name, test.supplier.s_suppkey, test.supplier.s_name, test.supplier.s_address, test.supplier.s_phone, test.supplier.s_acctbal, test.supplier.s_comment", - " │ │ └─HashJoin_67 99997.20 47959797.44 ((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.nation.n_nationkey, test.supplier.s_nationkey)]", - " │ │ ├─ExchangeReceiver_76(Build) 5.00 1202425.23 ((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00) mpp[tiflash] ", - " │ │ │ └─ExchangeSender_75 5.00 1201930.23 (((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ │ │ └─Projection_74 5.00 1201930.23 ((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.nation.n_nationkey, test.nation.n_name", - " │ │ │ └─HashJoin_68 5.00 1201930.19 (((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.region.r_regionkey, test.nation.n_regionkey)]", - " │ │ │ ├─ExchangeReceiver_72(Build) 1.00 562979.73 (((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00) mpp[tiflash] ", - " │ │ │ │ └─ExchangeSender_71 1.00 562893.21 ((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00)) mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ │ │ │ └─Selection_70 1.00 562893.21 (cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00) mpp[tiflash] eq(test.region.r_name, \"ASIA\")", - " │ │ │ │ └─TableFullScan_69 5.00 562881.21 ((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:region keep order:false", - " │ │ │ └─TableFullScan_73(Probe) 25.00 638908.37 ((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:nation keep order:false", - " │ │ └─TableFullScan_77(Probe) 500000.00 45957361.46 ((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:supplier keep order:false", - " │ └─ExchangeReceiver_83(Probe) 40000000.00 6134107979.69 ((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", - " │ └─ExchangeSender_82 40000000.00 2934107979.69 (((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.partsupp.ps_suppkey, collate: binary]", - " │ └─TableFullScan_81 40000000.00 2934107979.69 ((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:partsupp keep order:false", - " └─ExchangeReceiver_126(Probe) 6417481.71 6970208370.33 (((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", - " └─ExchangeSender_125 6417481.71 6662169248.27 ((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.partsupp.ps_partkey, collate: binary], [name: Column#59, collate: binary]", - " └─Selection_93 6417481.71 6662169248.27 (cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] not(isnull(Column#59))", - " └─Projection_119 8021852.14 6642916803.14 (((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] Column#59, test.partsupp.ps_partkey", - " └─HashAgg_94 8021852.14 6642839793.36 ((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00 mpp[tiflash] group by:test.partsupp.ps_partkey, funcs:min(test.partsupp.ps_supplycost)->Column#59, funcs:firstrow(test.partsupp.ps_partkey)->test.partsupp.ps_partkey", - " └─ExchangeReceiver_118 8021852.14 6615847793.29 (((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", - " └─ExchangeSender_117 8021852.14 6230798890.71 ((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.partsupp.ps_partkey, collate: binary]", - " └─Projection_97 8021852.14 6230798890.71 (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.partsupp.ps_partkey, test.partsupp.ps_supplycost", - " └─Projection_116 8021852.14 6230721880.93 ((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.partsupp.ps_partkey, test.partsupp.ps_supplycost, test.partsupp.ps_suppkey", - " └─HashJoin_98 8021852.14 6230606366.26 (((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.supplier.s_suppkey, test.partsupp.ps_suppkey)]", - " ├─ExchangeReceiver_112(Build) 99997.20 32325058.09 (((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", - " │ └─ExchangeSender_111 99997.20 31525080.49 ((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.supplier.s_suppkey, collate: binary]", - " │ └─Projection_110 99997.20 31525080.49 (((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.supplier.s_suppkey", - " │ └─HashJoin_99 99997.20 31524600.51 ((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.nation.n_nationkey, test.supplier.s_nationkey)]", - " │ ├─ExchangeReceiver_108(Build) 5.00 1144591.84 ((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00) mpp[tiflash] ", - " │ │ └─ExchangeSender_107 5.00 1144471.84 (((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ │ └─Projection_106 5.00 1144471.84 ((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.nation.n_nationkey", - " │ │ └─HashJoin_100 5.00 1144471.81 (((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.region.r_regionkey, test.nation.n_regionkey)]", - " │ │ ├─ExchangeReceiver_104(Build) 1.00 562979.73 (((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00) mpp[tiflash] ", - " │ │ │ └─ExchangeSender_103 1.00 562893.21 ((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00)) mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", - " │ │ │ └─Selection_102 1.00 562893.21 (cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00) mpp[tiflash] eq(test.region.r_name, \"ASIA\")", - " │ │ │ └─TableFullScan_101 5.00 562881.21 ((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:region keep order:false", - " │ │ └─TableFullScan_105(Probe) 25.00 581450.00 ((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:nation keep order:false", - " │ └─TableFullScan_109(Probe) 500000.00 29580000.00 ((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:supplier keep order:false", - " └─ExchangeReceiver_115(Probe) 40000000.00 6134107979.69 ((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", - " └─ExchangeSender_114 40000000.00 2934107979.69 (((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.partsupp.ps_suppkey, collate: binary]", - " └─TableFullScan_113 40000000.00 2934107979.69 ((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:partsupp keep order:false" + "Projection_40 100.00 922571773.52 (((((((((((((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(158044.3476975649*filters(0.08)*tiflash_cpu_factor(2.4)))/5.00)) + ((exprCPU(158044.3476975649*0*tiflash_cpu_factor(2.4))) + (orderCPU(158044.3476975649*log(100)*tiflash_cpu_factor(2.4)))) + (topMem(100*240*tiflash_mem_factor(0.05))))*1.00)) + (net(100*rowsize(240)*tidb_flash_net_factor(2.2))))/15.00)*1.00) + ((exprCPU(100*0*tidb_cpu_factor(49.9))) + (orderCPU(100*log(100)*tidb_cpu_factor(49.9)))) + (topMem(100*240*tidb_mem_factor(0.2))))*1.00) + ((cpu(100*filters(0.08)*tidb_cpu_factor(49.9)))/5.00) root test.supplier.s_acctbal, test.supplier.s_name, test.nation.n_name, test.part.p_partkey, test.part.p_mfgr, test.supplier.s_address, test.supplier.s_phone, test.supplier.s_comment", + "└─TopN_45 100.00 922571693.68 ((((((((((((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(158044.3476975649*filters(0.08)*tiflash_cpu_factor(2.4)))/5.00)) + ((exprCPU(158044.3476975649*0*tiflash_cpu_factor(2.4))) + (orderCPU(158044.3476975649*log(100)*tiflash_cpu_factor(2.4)))) + (topMem(100*240*tiflash_mem_factor(0.05))))*1.00)) + (net(100*rowsize(240)*tidb_flash_net_factor(2.2))))/15.00)*1.00) + ((exprCPU(100*0*tidb_cpu_factor(49.9))) + (orderCPU(100*log(100)*tidb_cpu_factor(49.9)))) + (topMem(100*240*tidb_mem_factor(0.2))))*1.00 root test.supplier.s_acctbal:desc, test.nation.n_name, test.supplier.s_name, test.part.p_partkey, offset:0, count:100", + " └─TableReader_383 100.00 922533740.84 ((((((((((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(158044.3476975649*filters(0.08)*tiflash_cpu_factor(2.4)))/5.00)) + ((exprCPU(158044.3476975649*0*tiflash_cpu_factor(2.4))) + (orderCPU(158044.3476975649*log(100)*tiflash_cpu_factor(2.4)))) + (topMem(100*240*tiflash_mem_factor(0.05))))*1.00)) + (net(100*rowsize(240)*tidb_flash_net_factor(2.2))))/15.00)*1.00 root MppVersion: 3, data:ExchangeSender_382", + " └─ExchangeSender_382 100.00 13837953312.55 (((((((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(158044.3476975649*filters(0.08)*tiflash_cpu_factor(2.4)))/5.00)) + ((exprCPU(158044.3476975649*0*tiflash_cpu_factor(2.4))) + (orderCPU(158044.3476975649*log(100)*tiflash_cpu_factor(2.4)))) + (topMem(100*240*tiflash_mem_factor(0.05))))*1.00) mpp[tiflash] ExchangeType: PassThrough", + " └─TopN_381 100.00 13837953312.55 ((((((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(158044.3476975649*filters(0.08)*tiflash_cpu_factor(2.4)))/5.00)) + ((exprCPU(158044.3476975649*0*tiflash_cpu_factor(2.4))) + (orderCPU(158044.3476975649*log(100)*tiflash_cpu_factor(2.4)))) + (topMem(100*240*tiflash_mem_factor(0.05))))*1.00 mpp[tiflash] test.supplier.s_acctbal:desc, test.nation.n_name, test.supplier.s_name, test.part.p_partkey, offset:0, count:100", + " └─Projection_380 158044.35 13835432055.15 ((((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(158044.3476975649*filters(0.08)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.part.p_partkey, test.part.p_mfgr, test.supplier.s_name, test.supplier.s_address, test.supplier.s_phone, test.supplier.s_acctbal, test.supplier.s_comment, test.nation.n_name", + " └─Projection_377 158044.35 13835425986.24 (((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.nation.n_name, test.supplier.s_name, test.supplier.s_address, test.supplier.s_phone, test.supplier.s_acctbal, test.supplier.s_comment, test.part.p_partkey, test.part.p_mfgr, test.partsupp.ps_partkey, Column#59", + " └─HashJoin_376 158044.35 13835418400.11 ((((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1)))) + ((((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + ((((hashkey(158044.3476975649*2*tiflash_cpu_factor(2.4))) + (hashmem(158044.3476975649*288*tiflash_mem_factor(0.05))) + (hashbuild(158044.3476975649*tiflash_cpu_factor(2.4)))) + (cpu(158044.3476975649*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(6.4174817096649995e+06*2*tiflash_cpu_factor(2.4))) + (hashprobe(6.4174817096649995e+06*tiflash_cpu_factor(2.4)))) + (cpu(6.4174817096649995e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.part.p_partkey, test.partsupp.ps_partkey) eq(test.partsupp.ps_supplycost, Column#59)]", + " ├─ExchangeReceiver_92(Build) 158044.35 6848670154.37 ((((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00))) + (net(158044.3476975649*rowsize(288)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", + " │ └─ExchangeSender_91 158044.35 6803153382.24 (((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.part.p_partkey, collate: binary], [name: test.partsupp.ps_supplycost, collate: binary]", + " │ └─Projection_90 158044.35 6803153382.24 ((((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(158044.3476975649*filters(0.09999999999999999)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.nation.n_name, test.supplier.s_name, test.supplier.s_address, test.supplier.s_phone, test.supplier.s_acctbal, test.supplier.s_comment, test.partsupp.ps_supplycost, test.part.p_partkey, test.part.p_mfgr, test.partsupp.ps_suppkey", + " │ └─HashJoin_66 158044.35 6803145796.11 (((((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00)) + (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00)) + ((((hashkey(158044.34769756492*1*tiflash_cpu_factor(2.4))) + (hashmem(158044.34769756492*76.26*tiflash_mem_factor(0.05))) + (hashbuild(158044.34769756492*tiflash_cpu_factor(2.4)))) + (cpu(158044.34769756492*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + (cpu(8.021852137081249e+06*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.partsupp.ps_partkey, test.part.p_partkey)]", + " │ ├─ExchangeReceiver_89(Build) 158044.35 521421689.50 (((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00))) + ((net(158044.34769756492*rowsize(76.26)*tiflash_mpp_net_factor(1)))*3.00) mpp[tiflash] ", + " │ │ └─ExchangeSender_88 158044.35 485264303.64 ((cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00)) mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ │ └─Selection_87 158044.35 485264303.64 (cpu(197555.43462195614*filters(1)*tiflash_cpu_factor(2.4))) + (((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00) mpp[tiflash] like(test.part.p_type, \"%STEEL\", 92)", + " │ │ └─TableFullScan_86 197555.43 484790170.59 ((lm_col_scan(1.001e+07*logrowsize(16)*tiflash_scan_factor(11.6))) + (lm_rest_col_scan(197555.43462195614*logrowsize(60.260000000000005)*tiflash_scan_factor(11.6)*lm_scan_factor(1.5))))*1.00 mpp[tiflash] table:part pushed down filter:eq(test.part.p_size, 30), keep order:false", + " │ └─Projection_85(Probe) 8021852.14 6268435397.86 ((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.09)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.nation.n_name, test.supplier.s_name, test.supplier.s_address, test.supplier.s_phone, test.supplier.s_acctbal, test.supplier.s_comment, test.partsupp.ps_partkey, test.partsupp.ps_supplycost, test.partsupp.ps_suppkey", + " │ └─HashJoin_67 8021852.14 6268088853.85 (((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*215*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.supplier.s_suppkey, test.partsupp.ps_suppkey)]", + " │ ├─ExchangeReceiver_81(Build) 99997.20 69462555.35 (((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(215)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", + " │ │ └─ExchangeSender_80 99997.20 47963157.35 ((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.supplier.s_suppkey, collate: binary]", + " │ │ └─Projection_79 99997.20 47963157.35 (((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.07)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.nation.n_name, test.supplier.s_suppkey, test.supplier.s_name, test.supplier.s_address, test.supplier.s_phone, test.supplier.s_acctbal, test.supplier.s_comment", + " │ │ └─HashJoin_68 99997.20 47959797.44 ((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*33*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.nation.n_nationkey, test.supplier.s_nationkey)]", + " │ │ ├─ExchangeReceiver_77(Build) 5.00 1202425.23 ((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(33)*tiflash_mpp_net_factor(1)))*3.00) mpp[tiflash] ", + " │ │ │ └─ExchangeSender_76 5.00 1201930.23 (((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ │ │ └─Projection_75 5.00 1201930.23 ((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.nation.n_nationkey, test.nation.n_name", + " │ │ │ └─HashJoin_69 5.00 1201930.19 (((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.region.r_regionkey, test.nation.n_regionkey)]", + " │ │ │ ├─ExchangeReceiver_73(Build) 1.00 562979.73 (((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00) mpp[tiflash] ", + " │ │ │ │ └─ExchangeSender_72 1.00 562893.21 ((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00)) mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ │ │ │ └─Selection_71 1.00 562893.21 (cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00) mpp[tiflash] eq(test.region.r_name, \"ASIA\")", + " │ │ │ │ └─TableFullScan_70 5.00 562881.21 ((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:region keep order:false", + " │ │ │ └─TableFullScan_74(Probe) 25.00 638908.37 ((scan(25*logrowsize(45.07)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(45.07)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:nation keep order:false", + " │ │ └─TableFullScan_78(Probe) 500000.00 45957361.46 ((scan(500000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(218.01999999999998)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:supplier keep order:false", + " │ └─ExchangeReceiver_84(Probe) 40000000.00 6134107979.69 ((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", + " │ └─ExchangeSender_83 40000000.00 2934107979.69 (((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.partsupp.ps_suppkey, collate: binary]", + " │ └─TableFullScan_82 40000000.00 2934107979.69 ((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:partsupp keep order:false", + " └─ExchangeReceiver_127(Probe) 6417481.71 6970208370.33 (((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)))) + (net(6.4174817096649995e+06*rowsize(48)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", + " └─ExchangeSender_126 6417481.71 6662169248.27 ((cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.partsupp.ps_partkey, collate: binary], [name: Column#59, collate: binary]", + " └─Selection_94 6417481.71 6662169248.27 (cpu(8.021852137081249e+06*filters(1)*tiflash_cpu_factor(2.4))) + ((((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] not(isnull(Column#59))", + " └─Projection_120 8021852.14 6642916803.14 (((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] Column#59, test.partsupp.ps_partkey", + " └─HashAgg_95 8021852.14 6642839793.36 ((cpu(10*3*tiflash_cpu_factor(2.4))) + ((((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1)))) + (((agg(8.021852137081249e+06*aggs(2)*tiflash_cpu_factor(2.4))) + (group(8.021852137081249e+06*cols(0.01)*tiflash_cpu_factor(2.4))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashmem(8.021852137081249e+06*48*tiflash_mem_factor(0.05))) + (hashbuild(8.021852137081249e+06*tiflash_cpu_factor(2.4)))) + ((hashkey(8.021852137081249e+06*1*tiflash_cpu_factor(2.4))) + (hashprobe(8.021852137081249e+06*tiflash_cpu_factor(2.4)))))/5.00))*1.00 mpp[tiflash] group by:test.partsupp.ps_partkey, funcs:min(test.partsupp.ps_supplycost)->Column#59, funcs:firstrow(test.partsupp.ps_partkey)->test.partsupp.ps_partkey", + " └─ExchangeReceiver_119 8021852.14 6615847793.29 (((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00))) + (net(8.021852137081249e+06*rowsize(48)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", + " └─ExchangeSender_118 8021852.14 6230798890.71 ((((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.partsupp.ps_partkey, collate: binary]", + " └─Projection_98 8021852.14 6230798890.71 (((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00)) + ((cpu(8.021852137081249e+06*filters(0.02)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.partsupp.ps_partkey, test.partsupp.ps_supplycost", + " └─Projection_117 8021852.14 6230721880.93 ((((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(8.021852137081249e+06*filters(0.03)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.partsupp.ps_partkey, test.partsupp.ps_supplycost, test.partsupp.ps_suppkey", + " └─HashJoin_99 8021852.14 6230606366.26 (((((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1)))) + (((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1)))) + ((((hashkey(99997.20000000001*1*tiflash_cpu_factor(2.4))) + (hashmem(99997.20000000001*8*tiflash_mem_factor(0.05))) + (hashbuild(99997.20000000001*tiflash_cpu_factor(2.4)))) + (cpu(99997.20000000001*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(4e+07*1*tiflash_cpu_factor(2.4))) + (hashprobe(4e+07*tiflash_cpu_factor(2.4)))) + (cpu(4e+07*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.supplier.s_suppkey, test.partsupp.ps_suppkey)]", + " ├─ExchangeReceiver_113(Build) 99997.20 32325058.09 (((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + (net(99997.20000000001*rowsize(8)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", + " │ └─ExchangeSender_112 99997.20 31525080.49 ((((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.supplier.s_suppkey, collate: binary]", + " │ └─Projection_111 99997.20 31525080.49 (((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(99997.20000000001*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.supplier.s_suppkey", + " │ └─HashJoin_100 99997.20 31524600.51 ((((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(5*1*tiflash_cpu_factor(2.4))) + (hashmem(5*8*tiflash_mem_factor(0.05))) + (hashbuild(5*tiflash_cpu_factor(2.4)))) + (cpu(5*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(500000*1*tiflash_cpu_factor(2.4))) + (hashprobe(500000*tiflash_cpu_factor(2.4)))) + (cpu(500000*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.nation.n_nationkey, test.supplier.s_nationkey)]", + " │ ├─ExchangeReceiver_109(Build) 5.00 1144591.84 ((((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00))) + ((net(5*rowsize(8)*tiflash_mpp_net_factor(1)))*3.00) mpp[tiflash] ", + " │ │ └─ExchangeSender_108 5.00 1144471.84 (((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00)) mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ │ └─Projection_107 5.00 1144471.84 ((((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00) + ((cpu(5*filters(0.01)*tiflash_cpu_factor(2.4)))/5.00) mpp[tiflash] test.nation.n_nationkey", + " │ │ └─HashJoin_101 5.00 1144471.81 (((((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00)) + (((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00) + ((((hashkey(1*1*tiflash_cpu_factor(2.4))) + (hashmem(1*28.84*tiflash_mem_factor(0.05))) + (hashbuild(1*tiflash_cpu_factor(2.4)))) + (cpu(1*filters(0)*tiflash_cpu_factor(2.4))) + ((hashkey(25*1*tiflash_cpu_factor(2.4))) + (hashprobe(25*tiflash_cpu_factor(2.4)))) + (cpu(25*filters(0)*tiflash_cpu_factor(2.4))))/3.00))*1.00 mpp[tiflash] inner join, equal:[eq(test.region.r_regionkey, test.nation.n_regionkey)]", + " │ │ ├─ExchangeReceiver_105(Build) 1.00 562979.73 (((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00))) + ((net(1*rowsize(28.84)*tiflash_mpp_net_factor(1)))*3.00) mpp[tiflash] ", + " │ │ │ └─ExchangeSender_104 1.00 562893.21 ((cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00)) mpp[tiflash] ExchangeType: Broadcast, Compression: FAST", + " │ │ │ └─Selection_103 1.00 562893.21 (cpu(5*filters(1)*tiflash_cpu_factor(2.4))) + (((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00) mpp[tiflash] eq(test.region.r_name, \"ASIA\")", + " │ │ │ └─TableFullScan_102 5.00 562881.21 ((scan(5*logrowsize(28.84)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(28.84)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:region keep order:false", + " │ │ └─TableFullScan_106(Probe) 25.00 581450.00 ((scan(25*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:nation keep order:false", + " │ └─TableFullScan_110(Probe) 500000.00 29580000.00 ((scan(500000*logrowsize(32)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(32)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:supplier keep order:false", + " └─ExchangeReceiver_116(Probe) 40000000.00 6134107979.69 ((((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00)) + (net(4e+07*rowsize(80)*tiflash_mpp_net_factor(1))) mpp[tiflash] ", + " └─ExchangeSender_115 40000000.00 2934107979.69 (((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00) mpp[tiflash] ExchangeType: HashPartition, Compression: FAST, Hash Cols: [name: test.partsupp.ps_suppkey, collate: binary]", + " └─TableFullScan_114 40000000.00 2934107979.69 ((scan(4e+07*logrowsize(80)*tiflash_scan_factor(11.6))) + (scan(10000*logrowsize(80)*tiflash_scan_factor(11.6))))*1.00 mpp[tiflash] table:partsupp keep order:false" ] } ] diff --git a/pkg/planner/core/exhaust_physical_plans.go b/pkg/planner/core/exhaust_physical_plans.go index 7c253cd980502..9a21391ea1574 100644 --- a/pkg/planner/core/exhaust_physical_plans.go +++ b/pkg/planner/core/exhaust_physical_plans.go @@ -330,6 +330,8 @@ func constructIndexJoinStatic( // for static enumeration here, we just pass down the original equal condition for condition adjustment rather // depend on the original logical join node. EqualConditions: p.EqualConditions, + // Only count candidates that keep the original Apply outer/inner order. + FromDecorrelatedApply: p.FromDecorrelatedApply && outerIdx == 0, }.Init(p.SCtx(), p.StatsInfo().ScaleByExpectCnt(p.SCtx().GetSessionVars(), prop.ExpectedCnt), p.QueryBlockOffset(), chReqProps...) join.SetSchema(p.Schema()) return []base.PhysicalPlan{join} diff --git a/pkg/planner/core/expression_rewriter.go b/pkg/planner/core/expression_rewriter.go index 905ae282230c1..9541664c852f8 100644 --- a/pkg/planner/core/expression_rewriter.go +++ b/pkg/planner/core/expression_rewriter.go @@ -373,6 +373,8 @@ type expressionRewriter struct { disableFoldCounter int tryFoldCounter int + astNodeStack []ast.Node + planCtx *exprRewriterPlanCtx } @@ -526,6 +528,7 @@ func (er *expressionRewriter) requirePlanCtx(inNode ast.Node, detail string) (ct // Enter implements Visitor interface. func (er *expressionRewriter) Enter(inNode ast.Node) (ast.Node, bool) { + er.astNodeStack = append(er.astNodeStack, inNode) enterWithPlanCtx := func(fn func(*exprRewriterPlanCtx) (ast.Node, bool)) (ast.Node, bool) { planCtx, err := er.requirePlanCtx(inNode, "") if err != nil { @@ -679,6 +682,67 @@ func (er *expressionRewriter) Enter(inNode ast.Node) (ast.Node, bool) { return inNode, false } +// inDirectMatchBooleanContext reports whether the MATCH...AGAINST currently +// being rewritten sits in a position where its boolean (0/1) result is +// directly consumed as a predicate — i.e. every ancestor up to the WHERE / +// HAVING / JOIN ON root is one of: parentheses, AND, OR, or NOT. +// +// Any other ancestor (comparison `= 0` / `> 0.5`, `IS NULL`, CASE, arithmetic, +// XOR, scalar function, etc.) means MATCH is being used as a scalar relevance +// score, where the LIKE rewrite's 0/1 output would diverge from the native +// float score and silently produce wrong rows. In those positions the +// rewriter must fall through to the native FTSMysqlMatchAgainst builtin, +// which preserves the relevance-score semantics (and errors at execution if +// no FTS index is available — the same behavior the user would see with +// alternative logical plans disabled). +func (er *expressionRewriter) inDirectMatchBooleanContext() bool { + if er.planCtx == nil { + return false + } + switch er.planCtx.builder.curClause { + case whereClause, havingClause, onClause: + default: + return false + } + if len(er.astNodeStack) == 0 { + return false + } + for i := len(er.astNodeStack) - 2; i >= 0; i-- { + switch n := er.astNodeStack[i].(type) { + case *ast.ParenthesesExpr: + case *ast.BinaryOperationExpr: + if n.Op != opcode.LogicAnd && n.Op != opcode.LogicOr { + return false + } + case *ast.UnaryOperationExpr: + if n.Op != opcode.Not && n.Op != opcode.Not2 { + return false + } + default: + return false + } + } + return true +} + +// matchHasLikeFallbackRescue reports whether matchAgainstToBuiltin is being +// invoked in a position where the alt-rounds driver will discard the produced +// plan and rebuild via the fts-like-fallback round. It is used by the modifier +// guard in matchAgainstToBuiltin to allow native emission of a non-default +// modifier when round 1's plan is destined for discard anyway. The rescue +// conditions mirror the ones in matchAgainstToExpression that trigger +// MarkNonViableFTSMatch — alternative logical plans enabled AND a direct +// boolean predicate context. +func (er *expressionRewriter) matchHasLikeFallbackRescue() bool { + if er.planCtx == nil || er.planCtx.builder == nil || er.planCtx.builder.ctx == nil { + return false + } + if !er.planCtx.builder.ctx.GetSessionVars().EnableAlternativeLogicalPlans { + return false + } + return er.inDirectMatchBooleanContext() +} + func (er *expressionRewriter) buildSemiApplyFromEqualSubq(np base.LogicalPlan, planCtx *exprRewriterPlanCtx, l, r expression.Expression, not, markNoDecorrelate bool) { intest.AssertNotNil(planCtx) if er.asScalar || not { @@ -1053,6 +1117,17 @@ func (er *expressionRewriter) handleExistSubquery(ctx context.Context, planCtx * // Add LIMIT 1 when noDecorrelate is true for EXISTS subqueries to enable early exit corCols := coreusage.ExtractCorColumnsBySchema4LogicalPlan(np, planCtx.plan.Schema()) noDecorrelate := isNoDecorrelate(planCtx, corCols, hintFlags, handlingExistsSubquery) + // When EnableCorrelateSubquery is ON (set by the correlate alternative round), + // prevent decorrelation of correlated subqueries so they stay as Apply with index lookups. + // Skip when SEMI_JOIN_REWRITE() hint is present, since that hint explicitly requires + // decorrelation and would be silently ineffective on LogicalApply nodes. + semiJoinRewriteHint := hintFlags&hint.HintFlagSemiJoinRewrite > 0 + if !noDecorrelate && len(corCols) > 0 && !semiJoinRewriteHint { + b.ctx.GetSessionVars().RecordRelevantOptVar(vardef.TiDBOptEnableAlternativeLogicalPlans) + if b.ctx.GetSessionVars().EnableCorrelateSubquery { + noDecorrelate = true + } + } if noDecorrelate { // Only add LIMIT 1 if the query doesn't already contain a LIMIT clause if !hasLimit(np) { @@ -1068,8 +1143,8 @@ func (er *expressionRewriter) handleExistSubquery(ctx context.Context, planCtx * } } np = er.popExistsSubPlan(planCtx, np) - semiJoinRewrite := hintFlags&hint.HintFlagSemiJoinRewrite > 0 - if semiJoinRewrite && noDecorrelate { + semiJoinRewrite := semiJoinRewriteHint + if semiJoinRewrite && hintFlags&hint.HintFlagNoDecorrelate > 0 { b.ctx.GetSessionVars().StmtCtx.SetHintWarning( "NO_DECORRELATE() and SEMI_JOIN_REWRITE() are in conflict. Both will be ineffective.") noDecorrelate = false @@ -1254,12 +1329,36 @@ func (er *expressionRewriter) handleInSubquery(ctx context.Context, planCtx *exp collFlag := collate.CompatibleCollate(lt.GetCollate(), rt.GetCollate()) corCols := coreusage.ExtractCorColumnsBySchema4LogicalPlan(np, planCtx.plan.Schema()) noDecorrelate := isNoDecorrelate(planCtx, corCols, hintFlags, handlingInSubquery) + // When EnableCorrelateSubquery is ON (set by the correlate alternative round), + // prevent decorrelation of correlated IN subqueries so they stay as Apply with index lookups. + if !noDecorrelate && len(corCols) > 0 && !v.Not { + planCtx.builder.ctx.GetSessionVars().RecordRelevantOptVar(vardef.TiDBOptEnableAlternativeLogicalPlans) + if planCtx.builder.ctx.GetSessionVars().EnableAlternativeLogicalPlans { + planCtx.builder.ctx.GetSessionVars().StmtCtx.MarkAlternativeLogicalPlanPreferCorrelate() + } + if planCtx.builder.ctx.GetSessionVars().EnableCorrelateSubquery { + noDecorrelate = true + } + } // If it's not the form of `not in (SUBQUERY)`, // and has no correlated column from the current level plan(if the correlated column is from upper level, // we can treat it as constant, because the upper LogicalApply cannot be eliminated since current node is a join node), // and don't need to append a scalar value, we can rewrite it to inner join. - if planCtx.builder.ctx.GetSessionVars().GetAllowInSubqToJoinAndAgg() && !v.Not && !asScalar && len(corCols) == 0 && collFlag { + // When EnableCorrelateSubquery is ON (set by the correlate alternative round), skip the + // InnerJoin+Agg rewrite so that a SemiJoin is built instead; the CorrelateSolver rule can + // then convert it to a correlated Apply with index lookups. + canRewriteToJoinAgg := planCtx.builder.ctx.GetSessionVars().GetAllowInSubqToJoinAndAgg() && !v.Not && !asScalar && len(corCols) == 0 && collFlag + if canRewriteToJoinAgg { + // Record that the alternative logical plans variable is relevant — toggling it + // changes whether we take the InnerJoin+Agg path or the SemiApply path. + planCtx.builder.ctx.GetSessionVars().RecordRelevantOptVar(vardef.TiDBOptEnableAlternativeLogicalPlans) + // Signal that a correlate alternative round is worth attempting. + if planCtx.builder.ctx.GetSessionVars().EnableAlternativeLogicalPlans { + planCtx.builder.ctx.GetSessionVars().StmtCtx.MarkAlternativeLogicalPlanPreferCorrelate() + } + } + if canRewriteToJoinAgg && !planCtx.builder.ctx.GetSessionVars().EnableCorrelateSubquery { // We need to try to eliminate the agg and the projection produced by this operation. planCtx.builder.optFlag |= rule.FlagEliminateAgg planCtx.builder.optFlag |= rule.FlagEliminateProjection @@ -1295,6 +1394,17 @@ func (er *expressionRewriter) handleInSubquery(ctx context.Context, planCtx *exp if er.err != nil { return v, true } + // When EnableCorrelateSubquery is ON (set by the correlate alternative round) + // and the subquery is non-correlated, mark the join so that CorrelateSolver + // converts it to a correlated Apply. + if len(corCols) == 0 && !v.Not { + planCtx.builder.ctx.GetSessionVars().RecordRelevantOptVar(vardef.TiDBOptEnableAlternativeLogicalPlans) + if planCtx.builder.ctx.GetSessionVars().EnableCorrelateSubquery { + if ap, ok := planCtx.plan.(*logicalop.LogicalApply); ok { + ap.PreferCorrelate = true + } + } + } } er.ctxStackPop(1) @@ -1481,6 +1591,11 @@ func (er *expressionRewriter) adjustUTF8MB4Collation(tp *types.FieldType) { // Leave implements Visitor interface. func (er *expressionRewriter) Leave(originInNode ast.Node) (retNode ast.Node, ok bool) { + defer func() { + if len(er.astNodeStack) > 0 { + er.astNodeStack = er.astNodeStack[:len(er.astNodeStack)-1] + } + }() if er.err != nil { return retNode, false } @@ -1697,41 +1812,7 @@ func (er *expressionRewriter) Leave(originInNode ast.Node) (retNode ast.Node, ok er.ctxStack[len(er.ctxStack)-1].SetCoercibility(expression.CoercibilityExplicit) er.ctxStack[len(er.ctxStack)-1].SetCharsetAndCollation(arg.GetType(er.sctx.GetEvalCtx()).GetCharset(), arg.GetType(er.sctx.GetEvalCtx()).GetCollate()) case *ast.MatchAgainst: - numCols := len(v.ColumnNames) - // The stack order is: col1, col2, ... colN, against - stackLen := len(er.ctxStack) - if stackLen < numCols+1 { - er.err = errors.Errorf("Unexpected stack length for MatchAgainst: %d", stackLen) - return retNode, false - } - against := er.ctxStack[stackLen-1] - cols := er.ctxStack[stackLen-numCols-1 : stackLen-1] - - args := make([]expression.Expression, 0, 1+numCols) - args = append(args, against) - args = append(args, cols...) - - er.ctxStackPop(numCols + 1) - fn, err := er.newFunction(ast.FTSMysqlMatchAgainst, &v.Type, args...) - if err != nil { - er.err = err - return retNode, false - } - sf, ok := fn.(*expression.ScalarFunction) - if !ok { - er.err = errors.Errorf("unexpected expression type for %s: %T", ast.FTSMysqlMatchAgainst, fn) - return retNode, false - } - if v.Modifier != ast.FulltextSearchModifierBooleanMode { - er.err = errors.Errorf("Currently TiDB only supports BOOLEAN MODE in MATCH AGAINST") - return retNode, false - } - if err := expression.SetFTSMysqlMatchAgainstModifier(sf, v.Modifier); err != nil { - er.err = err - return retNode, false - } - er.ctxStackAppend(fn, types.EmptyName) - er.planCtx.builder.ctx.SetHasFTSFunc() + er.matchAgainstToExpression(v) default: er.err = errors.Errorf("UnknownType: %T", v) return retNode, false @@ -2257,6 +2338,296 @@ func (er *expressionRewriter) patternLikeOrIlikeToExpression(v *ast.PatternLikeO er.ctxStackAppend(function, types.EmptyName) } +func (er *expressionRewriter) matchAgainstToExpression(v *ast.MatchAgainst) { + // Both the column expressions and Against expression have been visited + // and pushed onto the ctxStack. The stack layout is: + // [..., col1, col2, ..., colN, against] + numCols := len(v.ColumnNames) + stackLen := len(er.ctxStack) + if stackLen < numCols+1 { + er.err = errors.Errorf("Unexpected stack length for MatchAgainst: %d", stackLen) + return + } + + // Default behavior (Alt-disabled or Alt-enabled round 1) is to emit the + // native FTSMysqlMatchAgainst builtin. The alternative-rounds driver flips + // AlternativeLogicalPlanFTSLikeFallback to true and re-runs the build + // only when round 1 reported a direct-boolean-context MATCH that the + // native builtin cannot serve (no FTS index on a TiFlash replica / + // modifier not pushdown-supported). In that second pass the rewriter + // emits ILIKE for direct-boolean-context MATCH only — scoring contexts + // (SELECT field list / ORDER BY) and scalar predicate positions + // (IS NULL, comparisons, CASE, arithmetic) need the float relevance + // score, so they keep using the native builtin and will error at + // execution if no FTS index exists there. + // + // "Direct boolean context" requires that every ancestor up to the + // WHERE/HAVING/ON root is AND/OR/NOT/parens — see inDirectMatchBooleanContext. + // Limiting the LIKE rewrite to that subset preserves the 0/1-vs-float + // distinction: in scalar positions, `MATCH(...) IS NULL`, `MATCH(...) > 0.5`, + // etc. would silently produce wrong rows if the LIKE rewrite's integer + // result were substituted for the native float score. + // + // Round 1 also has to record viability before committing to native: if + // any boolean-context MATCH is non-viable, the resulting plan would + // fail at execution. The rewriter records that on the planBuilder so the + // round driver can invalidate the plan and trigger the fallback round. + // Round 1 additionally records that a direct-boolean-context MATCH was + // seen so the driver runs the LIKE round for cost competition even when + // round 1's native plan is executable. + useLikeFallback := false + if er.planCtx != nil && er.planCtx.builder != nil && er.planCtx.builder.ctx != nil { + sessVars := er.planCtx.builder.ctx.GetSessionVars() + if er.inDirectMatchBooleanContext() { + if sessVars.StmtCtx.AlternativeLogicalPlanFTSLikeFallback { + // fts-like-fallback round: boolean-context MATCH rewrites to ILIKE. + useLikeFallback = true + } else if sessVars.EnableAlternativeLogicalPlans { + // Round 1 (native). Mark the build so the driver runs the LIKE + // round and cost-compares its plan against round 1's. If this + // MATCH cannot run natively, also mark the build as non-viable + // so the driver discards round 1's plan; the rewrite continues + // with the native builtin to keep round 1 internally consistent. + er.planCtx.builder.MarkPredicateMatch() + if !er.ftsNativeViable(v.Modifier, numCols, stackLen) { + er.planCtx.builder.MarkNonViableFTSMatch() + } + } + } + } + + if useLikeFallback { + er.matchAgainstToLike(v, numCols, stackLen) + } else { + er.matchAgainstToBuiltin(v, numCols, stackLen) + } +} + +// ftsNativeViable reports whether the MATCH(...) currently being rewritten +// can be served on TiFlash by the native FTSMysqlMatchAgainst builtin. It +// walks the resolved column FieldNames sitting on ctxNameStk (stack layout is +// [..., col1, ..., colN, against]) and requires for each column: +// - the originating table has an available TiFlash replica; +// - the column is covered by a public FULLTEXT index on that table. +// +// In addition, the modifier must be the default natural-language mode. Boolean +// mode and WITH QUERY EXPANSION are not encoded in the tipb pushdown today +// (only ScalarFuncSig_FTSMatchExpression is emitted regardless of modifier), +// so a native plan that wins on cost would execute on TiFlash with the modifier +// silently dropped. Until the modifier is carried in the pushdown protocol, we +// treat those modifiers as non-viable for native pushdown. +func (er *expressionRewriter) ftsNativeViable(modifier ast.FulltextSearchModifier, numCols, stackLen int) bool { + if numCols <= 0 { + return false + } + // fts native viable: only support boolean mode, others are not. + if !isFTSSupportedModifier(modifier) { + return false + } + builder := er.planCtx.builder + sessVars := builder.ctx.GetSessionVars() + nameStart := stackLen - numCols - 1 + for i := range numCols { + name := er.ctxNameStk[nameStart+i] + if name == nil { + return false + } + tblName := name.OrigTblName + if tblName.L == "" { + tblName = name.TblName + } + if tblName.L == "" { + return false + } + dbName := name.DBName + if dbName.L == "" { + dbName = ast.NewCIStr(sessVars.CurrentDB) + } + tblInfo, err := builder.is.TableInfoByName(dbName, tblName) + if err != nil { + return false + } + if tblInfo.TiFlashReplica == nil || !tblInfo.TiFlashReplica.Available || tblInfo.TiFlashReplica.Count == 0 { + return false + } + colName := name.OrigColName + if colName.L == "" { + colName = name.ColName + } + if !tableHasPublicFTSIndexOnColumn(tblInfo, colName.L) { + return false + } + } + return true +} + +// isFTSSupportedModifier returns true for currently supported FTS modifiers. (currently only boolean mode, compatible with fts branch code) +func isFTSSupportedModifier(modifier ast.FulltextSearchModifier) bool { + return !modifier.IsNaturalLanguageMode() && !modifier.WithQueryExpansion() +} + +// tableHasPublicFTSIndexOnColumn reports whether tblInfo has a public FULLTEXT +// index covering the given column. TiDB's FULLTEXT index is single-column, so +// each column in MATCH(...) needs its own FTS index for the native path to be +// viable. +func tableHasPublicFTSIndexOnColumn(tblInfo *model.TableInfo, columnNameL string) bool { + for _, idx := range tblInfo.Indices { + if idx.FullTextInfo == nil || !idx.IsPublic() { + continue + } + if idx.FindColumnByName(columnNameL) != nil { + return true + } + } + return false +} + +// matchAgainstToBuiltin converts MATCH...AGAINST to the FTSMysqlMatchAgainst +// builtin scalar function which can be pushed down to TiFlash for execution +// against a fulltext index. +func (er *expressionRewriter) matchAgainstToBuiltin(v *ast.MatchAgainst, numCols, stackLen int) { + // Reject non-default modifiers when native is the final plan. The tipb + // pushdown protocol (see expression/distsql_builtin.go for the explicit + // note) does not serialize the FTS modifier, so TiFlash would silently + // execute Boolean-mode / query-expansion searches as natural-language + // mode. Until the modifier rides through pushdown, refuse to emit + // native here unless the alt-rounds driver is expected to discard this + // emission and rebuild via the fts-like-fallback round (which handles + // Boolean mode correctly via ILIKE; query expansion still errors there + // with a specific message). + // + // merge detail: here we allow natural language mode, boolean mode and query expansion mode + // natural language mode: can be written as ILike(round2) + // boolean mode: can be executed on tiFlash(round1) or through ILike rewrite(round2) + // query expansion mode: can error out with a specific message in both rounds. + if !isFTSSupportedModifier(v.Modifier) && !er.matchHasLikeFallbackRescue() { + er.err = expression.ErrNotSupportedYet.GenWithStackByArgs( + "MATCH...AGAINST with this modifier on the native FTS path (modifier is not carried through pushdown to TiFlash)") + return + } + + against := er.ctxStack[stackLen-1] + cols := er.ctxStack[stackLen-numCols-1 : stackLen-1] + + args := make([]expression.Expression, 0, 1+numCols) + args = append(args, against) + args = append(args, cols...) + + er.ctxStackPop(numCols + 1) + fn, err := er.newFunction(ast.FTSMysqlMatchAgainst, &v.Type, args...) + if err != nil { + er.err = err + return + } + sf, ok := fn.(*expression.ScalarFunction) + if !ok { + er.err = errors.Errorf("unexpected expression type for %s: %T", ast.FTSMysqlMatchAgainst, fn) + return + } + // merge detail: common set modifier interface. + if err := expression.SetFTSMysqlMatchAgainstModifier(sf, v.Modifier); err != nil { + er.err = err + return + } + er.ctxStackAppend(fn, types.EmptyName) +} + +// matchAgainstToLike converts MATCH...AGAINST to LIKE predicates as a +// fallback when the native FTS pushdown path is not viable. +func (er *expressionRewriter) matchAgainstToLike(v *ast.MatchAgainst, numCols, stackLen int) { + againstExpr := er.ctxStack[stackLen-1] + + constExpr, ok := againstExpr.(*expression.Constant) + if !ok { + er.err = expression.ErrNotSupportedYet.GenWithStackByArgs("MATCH...AGAINST with non-constant search string") + return + } + + // The LIKE fallback bakes the search value into the produced plan — either + // as ILIKE pattern constants (non-NULL case) or as a Constant(NULL) + // short-circuit. A cached plan would reuse the first execution's baked + // value for later executions, producing wrong results whenever the AGAINST + // argument is mutable: a `?` parameter marker, a user variable, or another + // deferred expression. In particular, a NULL first bind would bake a + // Constant(NULL) plan and reuse it for a later non-NULL bind. Mark the + // plan non-cacheable here, before the NULL fast-path and before Eval, so + // the skip applies uniformly across all branches below. + if expression.MaybeOverOptimized4PlanCache(er.sctx, constExpr) { + er.sctx.SetSkipPlanCache("MATCH...AGAINST LIKE fallback bakes a mutable search string into plan constants") + } + + // Reject non-string matched columns before any value-based branch so the + // column-type error always wins. In current architecture round 1's + // matchAgainstToBuiltin → getFunction (builtin_fts.go) already rejects + // non-string columns before round 2 (this function) can run, but keep + // the check here too as defense in depth: the LIKE fallback's own NULL + // fast-path and strict-subset validator below should never accept a + // non-string column, regardless of any future code path that might + // reach this function around round 1. + columns := make([]expression.Expression, numCols) + for i := range numCols { + col := er.ctxStack[stackLen-numCols-1+i] + if col.GetType(er.sctx.GetEvalCtx()).EvalType() != types.ETString { + er.err = expression.ErrNotSupportedYet.GenWithStackByArgs("Doesn't support match search on a non-string column without fulltext index") + return + } + columns[i] = col + } + + searchText, err := constExpr.Eval(er.sctx.GetEvalCtx(), chunk.Row{}) + if err != nil { + er.err = err + return + } + + if searchText.IsNull() { + // NULL search yields NULL in MySQL FTS semantics + // (builtin_fts.go evalReal returns isNull=true for NULL args), so we + // emit Constant(NULL) rather than Constant(0). This preserves + // three-valued logic under NOT — NOT NULL = NULL filters the row — + // and under IS NULL / IS NOT NULL. A literal Constant(0) would make + // NOT(MATCH...) admit every row when the search is NULL, diverging + // from native semantics. + er.ctxStackPop(numCols + 1) + er.ctxStackAppend(&expression.Constant{ + Value: types.Datum{}, + RetType: types.NewFieldType(mysql.TypeTiny), + }, types.EmptyName) + return + } + + if searchText.Kind() != types.KindString { + er.err = expression.ErrNotSupportedYet.GenWithStackByArgs("MATCH...AGAINST with non-string search expression") + return + } + + // The LIKE fallback only translates a strict subset of MySQL FTS search + // strings (alphanumeric words, optionally prefixed with + or - in boolean + // mode). Anything outside that subset would tokenize differently in MySQL + // FTS than a substring LIKE match, so refuse it here. If the same MATCH + // is independently native-viable (FTS index + supported modifier), + // delegate to the native builtin so TiFlash serves it correctly; otherwise + // surface the error to the user. + if err := expression.ValidateFTSSearchStringForLikeFallback(searchText.GetString(), v.Modifier); err != nil { + if er.ftsNativeViable(v.Modifier, numCols, stackLen) { + er.matchAgainstToBuiltin(v, numCols, stackLen) + return + } + er.err = err + return + } + + er.ctxStackPop(numCols + 1) + + result, err := er.convertMatchAgainstToLike(columns, searchText.GetString(), v.Modifier) + if err != nil { + er.err = err + return + } + + er.ctxStackAppend(result, types.EmptyName) +} + func (er *expressionRewriter) regexpToScalarFunc(v *ast.PatternRegexpExpr) { l := len(er.ctxStack) er.err = expression.CheckArgsNotMultiColumnRow(er.ctxStack[l-2:]...) diff --git a/pkg/planner/core/fulltext_to_like.go b/pkg/planner/core/fulltext_to_like.go new file mode 100644 index 0000000000000..72f0cb04f519e --- /dev/null +++ b/pkg/planner/core/fulltext_to_like.go @@ -0,0 +1,76 @@ +// Copyright 2026 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package core + +import ( + "github.com/pingcap/tidb/pkg/expression" + "github.com/pingcap/tidb/pkg/parser/ast" +) + +// convertMatchAgainstToLike converts a MATCH...AGAINST expression to ILIKE +// predicates. It is a thin wrapper around expression.BuildFTSToILikeExpression; +// the conversion logic lives in pkg/expression so the same translation can be +// shared with cardinality-based selectivity estimation (which substitutes the +// equivalent ILIKE form for the opaque FTSMysqlMatchAgainst builtin). +// +// This is a fallback rewrite since TiDB does not natively support full-text +// search outside the TiFlash FTS path. The planner only invokes it in +// direct-boolean predicate positions — every ancestor up to the +// WHERE / HAVING / JOIN ON root must be AND / OR / NOT / parens +// (see inDirectMatchBooleanContext in expression_rewriter.go). Scoring +// contexts (SELECT field list, ORDER BY) and scalar predicate positions +// (IS NULL, comparisons, CASE, arithmetic) keep the native +// FTSMysqlMatchAgainst builtin so the result is a float relevance score +// rather than 0/1, even though the native path then requires TiFlash at +// execution time. The semantic differences below therefore apply to +// direct-boolean predicate use only: +// +// 1. No relevance scoring — the synthesized ILIKE predicate produces a 0/1 +// boolean filter result, which is the only thing a direct-boolean +// predicate position consumes. Relevance-score positions (ORDER BY, +// scalar SELECT, MATCH ... = 0, MATCH ... > 0.5, etc.) are intentionally +// NOT routed through this fallback; substituting 0/1 there would +// silently corrupt the sort or the comparison. +// 2. No stop word filtering — searches for all words regardless of length +// or commonness. +// 3. No word length limits — MySQL ignores words shorter than +// ft_min_word_len (default 4); the ILIKE rewrite does not. +// 4. No word boundaries — LIKE %term% matches substrings anywhere, not just +// complete words. Example: "cat" matches "concatenate", "category", +// "application"; MySQL FTS only matches "cat" as a standalone word. +// Enforcing word boundaries would require REGEXP, which we avoid. +// 5. Performance — LIKE predicates cannot use full-text indexes (much +// slower on large datasets). +// +// Search-string subset accepted by the rewrite (enforced upstream by +// expression.ValidateFTSSearchStringForLikeFallback): +// +// - Natural-language mode: whitespace-separated alphanumeric words only. +// - Boolean mode: each token is `word`, `+word` (required), or `-word` +// (excluded), where `word` is alphanumeric (ASCII or non-ASCII UTF-8). +// +// Anything outside that subset — phrases, * prefix, > < ~ relevance +// modifiers, () grouping, mid-word punctuation like `xx-yy` — is rejected +// at plan time with ErrNotSupportedYet because MySQL FTS tokenizes those +// constructs in ways a substring LIKE cannot reproduce. WITH QUERY +// EXPANSION is likewise rejected (no LIKE approximation exists for the +// second-pass tokenization). +func (er *expressionRewriter) convertMatchAgainstToLike( + columns []expression.Expression, + searchText string, + modifier ast.FulltextSearchModifier, +) (expression.Expression, error) { + return expression.BuildFTSToILikeExpression(er.sctx, columns, searchText, modifier) +} diff --git a/pkg/planner/core/fulltext_to_like_test.go b/pkg/planner/core/fulltext_to_like_test.go new file mode 100644 index 0000000000000..9579bdd160757 --- /dev/null +++ b/pkg/planner/core/fulltext_to_like_test.go @@ -0,0 +1,134 @@ +// Copyright 2026 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package core + +import ( + "testing" + + "github.com/pingcap/tidb/pkg/meta/model" + "github.com/pingcap/tidb/pkg/parser/ast" + "github.com/stretchr/testify/require" +) + +func TestFTSModifierAllowsNativePushdown(t *testing.T) { + tests := []struct { + name string + modifier ast.FulltextSearchModifier + expected bool + }{ + { + name: "natural language mode (default)", + modifier: ast.FulltextSearchModifier(ast.FulltextSearchModifierNaturalLanguageMode), + expected: false, + }, + { + name: "boolean mode", + modifier: ast.FulltextSearchModifier(ast.FulltextSearchModifierBooleanMode), + expected: true, + }, + { + name: "natural language mode with query expansion", + modifier: ast.FulltextSearchModifier(ast.FulltextSearchModifierNaturalLanguageMode | ast.FulltextSearchModifierWithQueryExpansion), + expected: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require.Equal(t, tt.expected, isFTSSupportedModifier(tt.modifier)) + }) + } +} + +func TestTableHasPublicFTSIndexOnColumn(t *testing.T) { + ftsIdx := func(name, column string, state model.SchemaState) *model.IndexInfo { + return &model.IndexInfo{ + Name: ast.NewCIStr(name), + State: state, + Tp: ast.IndexTypeInvalid, + Columns: []*model.IndexColumn{{Name: ast.NewCIStr(column)}}, + FullTextInfo: &model.FullTextIndexInfo{ParserType: model.FullTextParserTypeStandardV1}, + } + } + plainIdx := func(name, column string) *model.IndexInfo { + return &model.IndexInfo{ + Name: ast.NewCIStr(name), + State: model.StatePublic, + Tp: ast.IndexTypeBtree, + Columns: []*model.IndexColumn{{Name: ast.NewCIStr(column)}}, + } + } + + tests := []struct { + name string + indices []*model.IndexInfo + column string + expected bool + }{ + { + name: "no indices", + indices: nil, + column: "title", + expected: false, + }, + { + name: "only non-FTS index on the column", + indices: []*model.IndexInfo{plainIdx("idx_title", "title")}, + column: "title", + expected: false, + }, + { + name: "public FTS index on the column", + indices: []*model.IndexInfo{ftsIdx("ft_title", "title", model.StatePublic)}, + column: "title", + expected: true, + }, + { + name: "non-public FTS index on the column", + indices: []*model.IndexInfo{ftsIdx("ft_title", "title", model.StateWriteReorganization)}, + column: "title", + expected: false, + }, + { + name: "FTS index on a different column", + indices: []*model.IndexInfo{ftsIdx("ft_body", "body", model.StatePublic)}, + column: "title", + expected: false, + }, + { + name: "FTS index covers the column among many indices", + indices: []*model.IndexInfo{ + plainIdx("idx_id", "id"), + ftsIdx("ft_body", "body", model.StatePublic), + ftsIdx("ft_title", "title", model.StatePublic), + }, + column: "title", + expected: true, + }, + { + name: "case-insensitive column match", + indices: []*model.IndexInfo{ftsIdx("ft_title", "Title", model.StatePublic)}, + column: "title", + expected: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tblInfo := &model.TableInfo{Indices: tt.indices} + require.Equal(t, tt.expected, tableHasPublicFTSIndexOnColumn(tblInfo, tt.column)) + }) + } +} diff --git a/pkg/planner/core/joinorder/BUILD.bazel b/pkg/planner/core/joinorder/BUILD.bazel index af9d0ae09f67f..696cf206dade3 100644 --- a/pkg/planner/core/joinorder/BUILD.bazel +++ b/pkg/planner/core/joinorder/BUILD.bazel @@ -1,16 +1,41 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "joinorder", - srcs = ["util.go"], + srcs = [ + "conflict_detector.go", + "join_order.go", + "ordered_leading.go", + "util.go", + ], importpath = "github.com/pingcap/tidb/pkg/planner/core/joinorder", visibility = ["//visibility:public"], deps = [ + "//pkg/expression", + "//pkg/meta/model", "//pkg/parser/ast", + "//pkg/parser/mysql", "//pkg/planner/core/base", "//pkg/planner/core/operator/logicalop", "//pkg/planner/util", "//pkg/util/hint", "//pkg/util/intest", + "//pkg/util/intset", + "//pkg/util/logutil", + "@com_github_cockroachdb_errors//:errors", + "@com_github_pingcap_errors//:errors", + "@org_uber_go_zap//:zap", + ], +) + +go_test( + name = "joinorder_test", + timeout = "short", + srcs = ["bitset_bench_test.go"], + embed = [":joinorder"], + flaky = True, + deps = [ + "//pkg/util/intset", + "@com_github_bits_and_blooms_bitset//:bitset", ], ) diff --git a/pkg/planner/core/joinorder/bitset_bench_test.go b/pkg/planner/core/joinorder/bitset_bench_test.go new file mode 100644 index 0000000000000..65d22979c8756 --- /dev/null +++ b/pkg/planner/core/joinorder/bitset_bench_test.go @@ -0,0 +1,186 @@ +// Copyright 2026 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package joinorder + +import ( + "fmt" + "testing" + + "github.com/bits-and-blooms/bitset" + "github.com/pingcap/tidb/pkg/util/intset" +) + +type joinorderBenchCase struct { + name string + nodeCount int + edgeCount int +} + +type edgeFast struct { + tes intset.FastIntSet + left intset.FastIntSet + right intset.FastIntSet + rules []ruleFast +} + +type ruleFast struct { + from intset.FastIntSet + to intset.FastIntSet +} + +type edgeBit struct { + tes *bitset.BitSet + left *bitset.BitSet + right *bitset.BitSet + rules []ruleBit +} + +type ruleBit struct { + from *bitset.BitSet + to *bitset.BitSet +} + +func buildFastSingleton(idx int) intset.FastIntSet { + return intset.NewFastIntSet(idx) +} + +func buildBitSingleton(idx int) *bitset.BitSet { + bs := bitset.New(uint(idx + 1)) + bs.Set(uint(idx)) + return bs +} + +func buildFastEdges(nodes []intset.FastIntSet, edgeCount int) []edgeFast { + edges := make([]edgeFast, 0, edgeCount) + n := len(nodes) + for i := 0; i < edgeCount; i++ { + l := i % n + r := (i*7 + 3) % n + if r == l { + r = (r + 1) % n + } + extra := (i*11 + 1) % n + if extra == l || extra == r { + extra = (extra + 2) % n + } + tes := nodes[l].Union(nodes[r]).Union(nodes[extra]) + left := nodes[l] + right := nodes[r] + rules := []ruleFast{ + {from: right, to: left}, + {from: left, to: right}, + } + edges = append(edges, edgeFast{tes: tes, left: left, right: right, rules: rules}) + } + return edges +} + +func buildBitEdges(nodes []*bitset.BitSet, edgeCount int) []edgeBit { + edges := make([]edgeBit, 0, edgeCount) + n := len(nodes) + for i := 0; i < edgeCount; i++ { + l := i % n + r := (i*7 + 3) % n + if r == l { + r = (r + 1) % n + } + extra := (i*11 + 1) % n + if extra == l || extra == r { + extra = (extra + 2) % n + } + tes := nodes[l].Union(nodes[r]).Union(nodes[extra]) + left := nodes[l] + right := nodes[r] + rules := []ruleBit{ + {from: right, to: left}, + {from: left, to: right}, + } + edges = append(edges, edgeBit{tes: tes, left: left, right: right, rules: rules}) + } + return edges +} + +func BenchmarkJoinOrderConflictDetectorOps(b *testing.B) { + cases := []joinorderBenchCase{ + {name: "n16_e32", nodeCount: 16, edgeCount: 32}, + {name: "n32_e64", nodeCount: 32, edgeCount: 64}, + {name: "n64_e128", nodeCount: 64, edgeCount: 128}, + {name: "n128_e256", nodeCount: 128, edgeCount: 256}, + } + + for _, c := range cases { + fastNodes := make([]intset.FastIntSet, 0, c.nodeCount) + bitNodes := make([]*bitset.BitSet, 0, c.nodeCount) + for i := 0; i < c.nodeCount; i++ { + fastNodes = append(fastNodes, buildFastSingleton(i)) + bitNodes = append(bitNodes, buildBitSingleton(i)) + } + + fastEdges := buildFastEdges(fastNodes, c.edgeCount) + bitEdges := buildBitEdges(bitNodes, c.edgeCount) + + b.Run(fmt.Sprintf("fastintset/conflict/%s", c.name), func(b *testing.B) { + var sink bool + b.ResetTimer() + for i := 0; i < b.N; i++ { + ok := true + for _, e := range fastEdges { + s := e.left.Union(e.right) + if !e.tes.SubsetOf(s) || !e.tes.Intersects(e.left) || !e.tes.Intersects(e.right) { + ok = false + } + if !e.left.Intersection(e.tes).SubsetOf(e.left) || !e.right.Intersection(e.tes).SubsetOf(e.right) { + ok = false + } + for _, r := range e.rules { + if r.from.Intersects(s) && !r.to.SubsetOf(s) { + ok = false + } + } + } + sink = ok + } + if sink { + _ = sink + } + }) + + b.Run(fmt.Sprintf("bitset/conflict/%s", c.name), func(b *testing.B) { + var sink bool + b.ResetTimer() + for i := 0; i < b.N; i++ { + ok := true + for _, e := range bitEdges { + s := e.left.Union(e.right) + if !s.IsSuperSet(e.tes) || e.tes.IntersectionCardinality(e.left) == 0 || e.tes.IntersectionCardinality(e.right) == 0 { + ok = false + } + if !e.left.IsSuperSet(e.left.Intersection(e.tes)) || !e.right.IsSuperSet(e.right.Intersection(e.tes)) { + ok = false + } + for _, r := range e.rules { + if r.from.IntersectionCardinality(s) > 0 && !s.IsSuperSet(r.to) { + ok = false + } + } + } + sink = ok + } + if sink { + _ = sink + } + }) + } +} diff --git a/pkg/planner/core/joinorder/conflict_detector.go b/pkg/planner/core/joinorder/conflict_detector.go new file mode 100644 index 0000000000000..20f3d215b074c --- /dev/null +++ b/pkg/planner/core/joinorder/conflict_detector.go @@ -0,0 +1,990 @@ +// Copyright 2026 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package joinorder + +import ( + "maps" + "slices" + + "github.com/pingcap/errors" + "github.com/pingcap/tidb/pkg/expression" + "github.com/pingcap/tidb/pkg/parser/mysql" + "github.com/pingcap/tidb/pkg/planner/core/base" + "github.com/pingcap/tidb/pkg/planner/core/operator/logicalop" + "github.com/pingcap/tidb/pkg/util/intset" +) + +// This file implements the CD-C (Conflict Detection C) algorithm +// from the paper: +// +// "On the Correct and Complete Enumeration of the Core Search Space" +// — Guido Moerkotte, Pit Fender, Marius Eich (2013) +// +// # Overview +// +// CD-C determines which join reorderings are semantically valid when outer joins +// (and semi/anti joins) are present. The key insight is that, unlike pure inner +// joins, outer joins are neither associative nor commutative in general. +// Rearranging them arbitrarily can change query results. +// +// # Core Concepts +// +// TES (Total Eligibility Set): +// +// For each join predicate (edge), the TES records which base relations must be +// present in a candidate subgraph for that predicate to be applicable. It starts +// as the SES (Syntactic Eligibility Set, i.e. the relations referenced by the +// predicate) and is extended by conflict rules. +// +// Conflict Rules: +// +// A conflict rule {from → to} states: "if any relation in `from` appears in a +// candidate join's input set S, then every relation in `to` must also appear in S." +// These rules are derived by checking, for each pair of a parent edge and a child +// edge, whether the three properties — associativity (assoc), left-asscom, and +// right-asscom — hold for their join-type combination. When a property does NOT +// hold, a conflict rule is generated to prevent the invalid reordering. +// +// Validity Check: +// +// When the join enumerator proposes connecting two subgraphs (S1, S2), each edge +// checks: (1) its TES is a subset of S1 ∪ S2, (2) it intersects both S1 and S2, +// and (3) all conflict rules are satisfied. Only then is the join considered valid. +// +// # Rule Tables +// +// The three rule tables (assocRuleTable, leftAsscomRuleTable, rightAsscomRuleTable) +// encode, for every pair of join types, whether the corresponding algebraic property +// holds. They are derived from Table 2 and Table 3 of the paper. Since TiDB does not +// support FULL OUTER JOIN, many conditional entries (requiring null-rejection checks) +// reduce to unconditional values. See the comments on each table for details. + +// ConflictDetector builds a join graph from the original plan tree and attaches +// conflict rules to each edge. It is then used by the join enumerator (greedy or +// DP) to validate candidate join pairs at enumeration time. +// +// # Workflow +// +// The lifecycle has two phases: +// +// Phase 1 — Build (called once per join group): +// +// Build() walks the plan tree bottom-up via buildRecursive(). At each join +// node it creates one or more edges: +// - Inner join: each conjunct becomes a separate edge (makeInnerEdge()), +// expanding the search space. +// - Non-inner join: all predicates stay in a single edge (makeNonInnerEdge()), +// keeping the join atomic. +// For every new edge, makeEdge() computes its TES(calcSES()) and generates conflict rules +// by comparing it against child edges from both subtrees. +// +// Phase 2 — CheckConnection (called repeatedly by the join enumerator): +// +// CheckConnection(node1, node2) iterates over all edges and tests whether +// each edge can validly connect the two nodes. The check differs by join kind: +// - Inner edge (checkInnerEdgeApplicable): TES ⊆ (S1 ∪ S2) and TES intersects both +// S1 and S2, plus all conflict rules pass. +// - Non-inner edge (checkNonInnerEdgeApplicable): additionally requires that the +// original left/right vertexes (intersected with TES) are fully contained +// in node1/node2 respectively, preserving outer-join side semantics. +// When edges pass, MakeJoin() constructs the actual LogicalJoin plan from the +// collected edges and returns a new merged Node. +type ConflictDetector struct { + ctx base.PlanContext + groupRoot base.LogicalPlan + groupVertexes []*Node + innerEdges []*edge + nonInnerEdges []*edge + allInnerJoin bool +} + +// edge represents a single join predicate (or a group of predicates for non-inner +// joins) in the join graph. Each edge knows its join type, conditions, the base +// relations it originally connects (leftVertexes, rightVertexes), its TES, and +// any conflict rules that constrain how it may be applied. +type edge struct { + idx uint64 + joinType base.JoinType + eqConds []*expression.ScalarFunction + // nonEQConds are used in two situations: + // 1. store all non-eq conds for LogicalJoin, like otherCond, leftCond, or rightCond. + // 2. store selection conditions for LogicalSelection-derived edge, which are looked through during buildRecursive. + nonEQConds expression.CNFExprs + + // TES is the Total Eligibility Set: the set of base relations that must be + // present in the candidate subgraph for this edge to be applicable. + // For now, TES is totally same with SES, check the TODO in makeEdge(). + // Note: didn't use pointer for TES because FastIntSet is relatively small and copying it is cheap. + tes intset.FastIntSet + // rules are conflict rules {from → to} derived during Build. They encode + // reordering constraints imposed by non-assoc/l-asscom/r-asscom join-type combinations. + rules []*rule + // skipRules is true when the entire join group is inner-join-only, in which + // case conflict rules are unnecessary. + skipRules bool + + // leftEdges/rightEdges are the child edges from the left/right subtrees at + // build time. They are used to derive conflict rules for this edge. + leftEdges []*edge + rightEdges []*edge + leftVertexes intset.FastIntSet + rightVertexes intset.FastIntSet +} + +// TryCreateCartesianCheckResult creates a CheckConnectionResult representing a +// cartesian product between left and right nodes. +// +// When checkResult.Connected() returns false, there are actually two situations: +// 1. The two nodes are truly invalid to join (e.g. conflict rules forbid it). +// 2. The two nodes have no shared edge, but a cartesian join is still legal. +// +// checkResult.Connected() itself does not distinguish them — both return false. +// We can handle case 2 by adding a fallback "cross edge" when building the ConflictDetector, +// so that Connected() returns true. +// But for now, we take a simpler approach: checkResult.Connected() return false for above both situations, +// and let the caller explicitly call TryCreateCartesianCheckResult to construct a +// cartesian edge when the join group is all-inner-join. +// +// The cartesian edge is created in two situations (callers that pass allowNoEQ=true +// to checkConnectionAndMakeJoin): +// 1. A leading hint forces the connection (e.g. LEADING(R1, R3) when there is no +// predicate between R1 and R3). +// 2. The greedy enumerator's second pass, where allowing cartesian joins may find +// a better plan. See https://github.com/pingcap/tidb/issues/63290. +func (d *ConflictDetector) TryCreateCartesianCheckResult(left, right *Node) *CheckConnectionResult { + if !d.allInnerJoin { + return nil + } + cartesianEdge := d.makeEdge(base.InnerJoin, []expression.Expression{}, left.bitSet, right.bitSet, nil, nil) + return &CheckConnectionResult{ + node1: left, + node2: right, + appliedInnerEdges: []*edge{cartesianEdge}, + hasEQCond: false, + } +} + +func (d *ConflictDetector) iterateEdges(fn func(e *edge) bool) { + for _, e := range d.innerEdges { + if !fn(e) { + return + } + } + for _, e := range d.nonInnerEdges { + if !fn(e) { + return + } + } +} + +// rule is a conflict rule {from → to}: if any relation in `from` appears in the +// candidate set S, then every relation in `to` must also appear in S. Violating +// this would produce a semantically invalid join reordering. +type rule struct { + from intset.FastIntSet + to intset.FastIntSet +} + +// Node represents either a leaf vertex (a single base relation) or an +// intermediate result (a join of two nodes). During enumeration, the greedy +// algorithm repeatedly merges two Nodes into one via MakeJoin(). +type Node struct { + // bitSet tracks which base relations (by index) are contained in this node. + bitSet intset.FastIntSet + p base.LogicalPlan + // cumCost is the cumulative cost (sum of row counts) of this node and all + // its descendants. It is used by the enumerator for join ordering. + cumCost float64 + // usedEdges records which edges have already been consumed by joins that + // produced this node. An edge must not be applied twice. + usedEdges map[uint64]struct{} +} + +func calcCumCost(p base.LogicalPlan, node1, node2 *Node) float64 { + var cost1, cost2 float64 + if node1 != nil { + cost1 = node1.cumCost + } + if node2 != nil { + cost2 = node2.cumCost + } + return p.StatsInfo().RowCount + cost1 + cost2 +} + +func calcCumCostByChildren(p base.LogicalPlan) float64 { + cost := p.StatsInfo().RowCount + for _, child := range p.Children() { + cost += calcCumCostByChildren(child) + } + return cost +} + +func (n *Node) checkUsedEdges(edgeIdx uint64) bool { + _, used := n.usedEdges[edgeIdx] + return used +} + +func newConflictDetector(ctx base.PlanContext) *ConflictDetector { + return &ConflictDetector{ + ctx: ctx, + } +} + +// Build constructs the join graph (edges + conflict rules) from a joinGroup. +// It returns the list of leaf Nodes (vertexes) of current join group, which will be merged to new join by the enumerator. +func (d *ConflictDetector) Build(group *joinGroup) ([]*Node, error) { + d.groupRoot = group.root + d.allInnerJoin = group.allInnerJoin + + vertexMap := make(map[int]*Node, len(group.vertexes)) + for i, v := range group.vertexes { + if _, _, err := v.RecursiveDeriveStats(nil); err != nil { + return nil, err + } + vertexMap[v.ID()] = &Node{ + bitSet: intset.NewFastIntSet(i), + p: v, + cumCost: calcCumCostByChildren(v), + } + } + + if _, _, err := d.buildRecursive(group, group.root, vertexMap); err != nil { + return nil, err + } + return d.groupVertexes, nil +} + +// buildRecursive walks the plan tree bottom-up. For each join node, it: +// 1. Recurses into left and right children to collect their edges and vertex sets. +// 2. Creates new edge(s) for the current join operator. +// 3. Returns the accumulated edges and the union of all vertex sets seen so far. +// +// The returned edges list is used by parent calls to generate conflict rules. +func (d *ConflictDetector) buildRecursive(group *joinGroup, p base.LogicalPlan, vertexMap map[int]*Node) ([]*edge, intset.FastIntSet, error) { + if vertexNode, ok := vertexMap[p.ID()]; ok { + d.groupVertexes = append(d.groupVertexes, vertexNode) + return nil, vertexNode.bitSet, nil + } + + // Look through Selection nodes that were kept in the original tree + // (e.g., Selection between two joins in a nested case). + if sel, ok := p.(*logicalop.LogicalSelection); ok { + childEdges, childVertexes, err := d.buildRecursive(group, sel.Children()[0], vertexMap) + if err != nil { + return nil, intset.FastIntSet{}, err + } + selID := sel.ID() + conds, ok := group.selConds[selID] + if !ok { + return nil, intset.FastIntSet{}, errors.Errorf("unexpected Selection node (ID: %d) found in buildRecursive", selID) + } + // Create a Selection edge for filter conditions collected from Selection + // operators that were looked through during extractJoinGroup. + // Selection-derived edge doesn't have child-edges and child-vertexes, + // because no need to generate ConflictRule for this edge. + // But its TES is its all children vertexes for correctness. + selEdge := d.makeEdgeInternal(base.InnerJoin, intset.FastIntSet{}, intset.FastIntSet{}, nil, nil, childVertexes) + selEdge.nonEQConds = conds + return append(childEdges, selEdge), childVertexes, nil + } + + var curVertexes intset.FastIntSet + // All internal nodes in the join group should be join operators. + joinop, ok := p.(*logicalop.LogicalJoin) + if !ok { + return nil, intset.FastIntSet{}, errors.New("unexpected plan type in conflict detector") + } + + leftEdges, leftVertexes, err := d.buildRecursive(group, joinop.Children()[0], vertexMap) + if err != nil { + return nil, curVertexes, err + } + rightEdges, rightVertexes, err := d.buildRecursive(group, joinop.Children()[1], vertexMap) + if err != nil { + return nil, curVertexes, err + } + + var curEdges []*edge + if joinop.JoinType == base.InnerJoin { + if curEdges, err = d.makeInnerEdge(joinop, leftVertexes, rightVertexes, leftEdges, rightEdges); err != nil { + return nil, curVertexes, err + } + } else { + curEdge, err := d.makeNonInnerEdge(joinop, leftVertexes, rightVertexes, leftEdges, rightEdges) + if err != nil { + return nil, curVertexes, err + } + curEdges = []*edge{curEdge} + } + if leftVertexes.Intersects(rightVertexes) { + return nil, curVertexes, errors.New("conflicting join edges detected") + } + curVertexes = leftVertexes.Union(rightVertexes) + + return append(leftEdges, append(rightEdges, curEdges...)...), curVertexes, nil +} + +// makeInnerEdge splits an inner join into one edge per conjunct (eq-cond or +// non-eq-cond). We can enlarges the search space by allowing each predicate +// to be applied independently. +// For example: (R1 INNER JOIN R2 on P12) INNER JOIN R3 on P13 and P23 +// By spliting the CNF join condition of INNER JOIN, R2 and R3 can also be connected using P23. +func (d *ConflictDetector) makeInnerEdge(joinop *logicalop.LogicalJoin, leftVertexes, rightVertexes intset.FastIntSet, leftEdges, rightEdges []*edge) (res []*edge, err error) { + if len(joinop.NAEQConditions) > 0 { + return nil, errors.New("NAEQConditions not supported in conflict detector yet") + } + + conds := expression.ScalarFuncs2Exprs(joinop.EqualConditions) + nonEQConds := make([]expression.Expression, 0, len(joinop.LeftConditions)+len(joinop.RightConditions)+len(joinop.OtherConditions)) + nonEQConds = append(nonEQConds, joinop.OtherConditions...) + nonEQConds = append(nonEQConds, joinop.LeftConditions...) + nonEQConds = append(nonEQConds, joinop.RightConditions...) + + if len(conds) == 0 && len(nonEQConds) == 0 { + tmp := d.makeEdge(base.InnerJoin, []expression.Expression{}, leftVertexes, rightVertexes, leftEdges, rightEdges) + res = append(res, tmp) + } + + condArg := make([]expression.Expression, 1) + for _, cond := range conds { + condArg[0] = cond + tmp := d.makeEdge(base.InnerJoin, condArg, leftVertexes, rightVertexes, leftEdges, rightEdges) + tmp.eqConds = append(tmp.eqConds, cond.(*expression.ScalarFunction)) + res = append(res, tmp) + } + + for _, cond := range nonEQConds { + condArg[0] = cond + tmp := d.makeEdge(base.InnerJoin, condArg, leftVertexes, rightVertexes, leftEdges, rightEdges) + tmp.nonEQConds = append(tmp.nonEQConds, cond) + res = append(res, tmp) + } + return +} + +// makeNonInnerEdge creates a single edge for a non-inner join. Unlike inner +// joins, all predicates are kept together because outer/semi/anti joins are +// atomic — their predicates cannot be applied independently. +func (d *ConflictDetector) makeNonInnerEdge(joinop *logicalop.LogicalJoin, leftVertexes, rightVertexes intset.FastIntSet, leftEdges, rightEdges []*edge) (*edge, error) { + if len(joinop.NAEQConditions) > 0 { + return nil, errors.New("NAEQConditions not supported in conflict detector yet") + } + + nonEQConds := make([]expression.Expression, 0, len(joinop.LeftConditions)+len(joinop.RightConditions)+len(joinop.OtherConditions)) + nonEQConds = append(nonEQConds, joinop.LeftConditions...) + nonEQConds = append(nonEQConds, joinop.RightConditions...) + nonEQConds = append(nonEQConds, joinop.OtherConditions...) + + conds := expression.ScalarFuncs2Exprs(joinop.EqualConditions) + if len(conds) == 0 && len(nonEQConds) == 0 { + return d.makeEdge(joinop.JoinType, []expression.Expression{}, leftVertexes, rightVertexes, leftEdges, rightEdges), nil + } + + conds = append(conds, nonEQConds...) + + e := d.makeEdge(joinop.JoinType, conds, leftVertexes, rightVertexes, leftEdges, rightEdges) + e.eqConds = make([]*expression.ScalarFunction, len(joinop.EqualConditions)) + copy(e.eqConds, joinop.EqualConditions) + e.nonEQConds = nonEQConds + + return e, nil +} + +// makeEdge basically implements the pseudocode for CD-C in paper(Figure-11). +func (d *ConflictDetector) makeEdge(joinType base.JoinType, conds []expression.Expression, leftVertexes, rightVertexes intset.FastIntSet, leftEdges, rightEdges []*edge) *edge { + // The following implements the first part of the pseudocode for CD-C in the paper(Figure-11): + // calc the SES(Syntactic Eligibility Set) and init TES(Total Eligibility Set) as SES. + tes := d.calcSES(conds) + return d.makeEdgeInternal(joinType, leftVertexes, rightVertexes, leftEdges, rightEdges, tes) +} + +func (d *ConflictDetector) makeEdgeInternal(joinType base.JoinType, leftVertexes, rightVertexes intset.FastIntSet, leftEdges, rightEdges []*edge, tes intset.FastIntSet) *edge { + e := &edge{ + // Each new edge is appended to either d.innerEdges or d.nonInnerEdges + // (see below), so their combined length before the append is the next + // available unique index. + idx: uint64(len(d.innerEdges) + len(d.nonInnerEdges)), + joinType: joinType, + leftVertexes: leftVertexes, + rightVertexes: rightVertexes, + leftEdges: leftEdges, + rightEdges: rightEdges, + skipRules: d.allInnerJoin, + tes: tes.Copy(), + } + + // The following corresponds to the secion 6.2 in the paper(Cross Products and Degenerate Predicates). + // For degenerate predicates (only one side referenced), force TES to include + // both sides so the edge can't connect unrelated subsets. + if !e.tes.Intersects(e.leftVertexes) { + e.tes = e.tes.Union(e.leftVertexes) + } + if !e.tes.Intersects(e.rightVertexes) { + e.tes = e.tes.Union(e.rightVertexes) + } + + if joinType == base.InnerJoin { + d.innerEdges = append(d.innerEdges, e) + } else { + d.nonInnerEdges = append(d.nonInnerEdges, e) + } + + // The following implements the conflict rule part of the pseudocode for CD-C in the paper(Figure-11). + // Conflict rules are generated by checking assoc / l-asscom / r-asscom for every + // (child, parent) edge pair. Skipped when all joins are inner joins, because + // inner joins are freely reorderable. + // + // TODO: Implement TES extension via conflict rules later. + // In the section 5.5 of the paper, TES will be extended by conflict rules. + // The current implementation does not do this step for now. + // We defer this because the greedy enumerator has a much smaller search space than DP, so the rule-check overhead is low. + if d.allInnerJoin { + return e + } + for _, child := range leftEdges { + if !assoc(child, e) { + e.rules = append(e.rules, rightToLeftRule(child)) + } + if !leftAsscom(child, e) { + e.rules = append(e.rules, leftToRightRule(child)) + } + } + for _, child := range rightEdges { + if !assoc(e, child) { + e.rules = append(e.rules, leftToRightRule(child)) + } + if !rightAsscom(e, child) { + e.rules = append(e.rules, rightToLeftRule(child)) + } + } + + return e +} + +// rightToLeftRule creates a conflict rule: if child's right vertexes appear in S, +// then child's left vertexes (or the subset intersecting TES) must also be in S. +// The name means "from right to left": the presence of right-side relations +// requires the presence of left-side relations. +func rightToLeftRule(child *edge) *rule { + rule := &rule{from: child.rightVertexes} + if child.leftVertexes.Intersects(child.tes) { + rule.to = child.leftVertexes.Intersection(child.tes) + } else { + rule.to = child.leftVertexes + } + return rule +} + +// leftToRightRule creates a conflict rule: if child's left vertexes appear in S, +// then child's right vertexes (or the subset intersecting TES) must also be in S. +// The name means "from left to right": the presence of left-side relations +// requires the presence of right-side relations. +func leftToRightRule(child *edge) *rule { + rule := &rule{from: child.leftVertexes} + if child.rightVertexes.Intersects(child.tes) { + rule.to = child.rightVertexes.Intersection(child.tes) + } else { + rule.to = child.rightVertexes + } + return rule +} + +func (d *ConflictDetector) calcSES(conds []expression.Expression) intset.FastIntSet { + var res intset.FastIntSet + for _, cond := range conds { + for _, node := range d.groupVertexes { + if expression.ExprReferenceSchema(cond, node.p.Schema()) { + res = res.Union(node.bitSet) + } + } + } + return res +} + +// joinTypeConvertTable maps base.JoinType to indices used in rule tables. +var joinTypeConvertTable = []int{ + 0, // INNER + 1, // LEFT OUTER + 2, // RIGHT OUTER + 3, // LEFT SEMI + 4, // LEFT ANTI + 3, // LEFT OUTER SEMI + 4, // ANTI LEFT OUTER SEMI +} + +func assoc(e1, e2 *edge) bool { + j1 := joinTypeConvertTable[e1.joinType] + j2 := joinTypeConvertTable[e2.joinType] + return assocRuleTable[j1][j2] == 1 +} + +func leftAsscom(e1, e2 *edge) bool { + j1 := joinTypeConvertTable[e1.joinType] + j2 := joinTypeConvertTable[e2.joinType] + return leftAsscomRuleTable[j1][j2] == 1 +} + +func rightAsscom(e1, e2 *edge) bool { + j1 := joinTypeConvertTable[e1.joinType] + j2 := joinTypeConvertTable[e2.joinType] + return rightAsscomRuleTable[j1][j2] == 1 +} + +// CheckConnectionResult contains the result of checking connection between two nodes. +type CheckConnectionResult struct { + node1 *Node + node2 *Node + appliedInnerEdges []*edge + appliedNonInnerEdge *edge + hasEQCond bool +} + +// Connected checks if two nodes are connected. +func (r *CheckConnectionResult) Connected() bool { + return len(r.appliedInnerEdges) > 0 || r.appliedNonInnerEdge != nil +} + +// NoEQEdge checks if there is no EQ edge between two nodes. +func (r *CheckConnectionResult) NoEQEdge() bool { + return !r.hasEQCond +} + +// CheckConnection tests whether any edge can validly connect node1 and node2. +// It's corresponding to the pseudocode for APPLICABLE(b/c) in the paper(Figure-9). +// The basic idea is: It collects all applicable inner edges (there can be many) and at most one +// non-inner edge. The result is later passed to MakeJoin() to build the plan. +func (d *ConflictDetector) CheckConnection(node1, node2 *Node) (*CheckConnectionResult, error) { + if node1 == nil || node2 == nil { + return nil, errors.Errorf("nil node found in CheckConnection, node1: %v, node2: %v", node1, node2) + } + + result := &CheckConnectionResult{} + for _, e := range d.innerEdges { + if node1.checkUsedEdges(e.idx) || node2.checkUsedEdges(e.idx) { + continue + } + if e.checkInnerEdgeApplicable(node1, node2) { + result.appliedInnerEdges = append(result.appliedInnerEdges, e) + result.hasEQCond = result.hasEQCond || len(e.eqConds) > 0 + } + } + var swapNode bool + for _, e := range d.nonInnerEdges { + if node1.checkUsedEdges(e.idx) || node2.checkUsedEdges(e.idx) { + continue + } + ok1 := e.checkNonInnerEdgeApplicable(node1, node2) + ok2 := e.checkNonInnerEdgeApplicable(node2, node1) + if ok1 && ok2 { + return nil, errors.New("node1 and node2 cannot be connected by non-inner edges of different direction") + } + if ok1 || ok2 { + if result.appliedNonInnerEdge != nil { + return nil, errors.New("multiple non-inner edges applied between two nodes") + } + result.appliedNonInnerEdge = e + result.hasEQCond = result.hasEQCond || len(e.eqConds) > 0 + // No need to worry about `swapNode` changing from true to false in the next loop, + // because an error will be returned if there are multiple different non-inner edges. + swapNode = ok2 + } + } + if swapNode { + result.node1 = node2 + result.node2 = node1 + } else { + result.node1 = node1 + result.node2 = node2 + } + return result, nil +} + +// checkInnerEdgeApplicable validates that this inner edge can connect node1 and node2. +// For inner joins the two sides are symmetric, so we only require: +// - All conflict rules are satisfied. +// - TES ⊆ (S1 ∪ S2): all required relations are present. +// - TES ∩ S1 ≠ ∅ and TES ∩ S2 ≠ ∅: the edge truly connects both sides. +func (e *edge) checkInnerEdgeApplicable(node1, node2 *Node) bool { + if !e.skipRules && !e.checkRules(node1, node2) { + return false + } + return e.tes.SubsetOf(node1.bitSet.Union(node2.bitSet)) && + e.tes.Intersects(node1.bitSet) && + e.tes.Intersects(node2.bitSet) +} + +// checkNonInnerEdgeApplicable validates that this non-inner edge can connect node1 (left) +// and node2 (right). Beyond the inner-edge checks, it enforces side semantics: +// the original left vertexes (∩ TES) must land entirely in node1, and the +// original right vertexes (∩ TES) must land entirely in node2. This prevents +// the outer-join's preserved side from being split across the two inputs. +func (e *edge) checkNonInnerEdgeApplicable(node1, node2 *Node) bool { + if !e.skipRules && !e.checkRules(node1, node2) { + return false + } + return e.leftVertexes.Intersection(e.tes).SubsetOf(node1.bitSet) && + e.rightVertexes.Intersection(e.tes).SubsetOf(node2.bitSet) && + e.tes.Intersects(node1.bitSet) && + e.tes.Intersects(node2.bitSet) +} + +// checkRules verifies that all conflict rules are satisfied for the candidate +// set S = S1 ∪ S2. A rule {from → to} fails if from ∩ S ≠ ∅ but to ⊄ S. +func (e *edge) checkRules(node1, node2 *Node) bool { + s := node1.bitSet.Union(node2.bitSet) + for _, r := range e.rules { + if r.from.Intersects(s) && !r.to.SubsetOf(s) { + return false + } + } + return true +} + +// MakeJoin construct a join plan from the check result. +func (d *ConflictDetector) MakeJoin(checkResult *CheckConnectionResult, vertexHints map[int]*JoinMethodHint) (*Node, error) { + numInnerEdges := len(checkResult.appliedInnerEdges) + var numNonInnerEdges int + if checkResult.appliedNonInnerEdge != nil { + numNonInnerEdges = 1 + } + + var err error + var p base.LogicalPlan + var newJoin *logicalop.LogicalJoin + // Note that non-inner edges should be processed first then inner edges, + // because inner joins can be appended to existing non-inner join as selections. + if numNonInnerEdges > 0 { + if newJoin, err = makeNonInnerJoin(d.ctx, checkResult, vertexHints); err != nil { + return nil, err + } + } + if numInnerEdges > 0 { + if p, err = makeInnerJoin(d.ctx, checkResult, newJoin, vertexHints); err != nil { + return nil, err + } + } else { + p = newJoin + } + if p == nil { + return nil, errors.New("failed to make join plan") + } + if _, _, err := p.RecursiveDeriveStats(nil); err != nil { + return nil, err + } + + node1 := checkResult.node1 + node2 := checkResult.node2 + usedEdges := make(map[uint64]struct{}, numInnerEdges+numNonInnerEdges+len(node1.usedEdges)+len(node2.usedEdges)) + for _, e := range checkResult.appliedInnerEdges { + usedEdges[e.idx] = struct{}{} + } + if checkResult.appliedNonInnerEdge != nil { + usedEdges[checkResult.appliedNonInnerEdge.idx] = struct{}{} + } + maps.Copy(usedEdges, node1.usedEdges) + maps.Copy(usedEdges, node2.usedEdges) + return &Node{ + bitSet: node1.bitSet.Union(node2.bitSet), + p: p, + cumCost: calcCumCost(p, node1, node2), + usedEdges: usedEdges, + }, nil +} + +func alignEQConds(ctx base.PlanContext, left, right base.LogicalPlan, eqConds []*expression.ScalarFunction) (newLeft base.LogicalPlan, newRight base.LogicalPlan, alignedEQConds []*expression.ScalarFunction, err error) { + if len(eqConds) == 0 { + return left, right, nil, nil + } + res := make([]*expression.ScalarFunction, 0, len(eqConds)) + for _, cond := range eqConds { + args := cond.GetArgs() + if len(args) != 2 { + return nil, nil, nil, errors.Errorf("unexpected eq condition args: %d", len(args)) + } + if expression.ExprFromSchema(args[0], left.Schema()) && expression.ExprFromSchema(args[1], right.Schema()) { + res = append(res, cond) + continue + } + if expression.ExprFromSchema(args[1], left.Schema()) && expression.ExprFromSchema(args[0], right.Schema()) { + swapped, ok := expression.NewFunctionInternal(ctx.GetExprCtx(), cond.FuncName.L, cond.GetStaticType(), args[1], args[0]).(*expression.ScalarFunction) + if !ok { + return nil, nil, nil, errors.New("failed to build swapped eq condition") + } + _, isCol0 := swapped.GetArgs()[0].(*expression.Column) + _, isCol1 := swapped.GetArgs()[1].(*expression.Column) + if !isCol0 || !isCol1 { + lCol := swapped.GetArgs()[0] + rCol := swapped.GetArgs()[1] + if !isCol0 { + left, lCol = logicalop.InjectExpr(left, swapped.GetArgs()[0]) + } + if !isCol1 { + right, rCol = logicalop.InjectExpr(right, swapped.GetArgs()[1]) + } + swapped = expression.NewFunctionInternal(ctx.GetExprCtx(), cond.FuncName.L, cond.GetStaticType(), + lCol, rCol).(*expression.ScalarFunction) + } + res = append(res, swapped) + continue + } + return nil, nil, nil, errors.New("eq condition does not match join sides") + } + return left, right, res, nil +} + +func makeNonInnerJoin(ctx base.PlanContext, checkResult *CheckConnectionResult, vertexHints map[int]*JoinMethodHint) (*logicalop.LogicalJoin, error) { + e := checkResult.appliedNonInnerEdge + var alignedEQConds []*expression.ScalarFunction + var err error + + checkResult.node1.p, checkResult.node2.p, alignedEQConds, err = alignEQConds(ctx, checkResult.node1.p, checkResult.node2.p, e.eqConds) + if err != nil { + return nil, err + } + + left := checkResult.node1.p + right := checkResult.node2.p + + join, err := newCartesianJoin(ctx, e.joinType, left, right, vertexHints) + if err != nil { + return nil, err + } + // After join reorder, the NOT_NULL flag of the null-producing side should be removed. + // We've done this for new join's output schema in LogicalJoin.MergeSchema(). + // Here we do the same thing for expressions in join conditions. + // For example: + // Before reorder: t1 left (t2 left t3 on t2.c2 = t3.c2) on t1.c1 = t2.c1 + // After reorder, (t1 left t2 on t1.c1 = t2.c1) left t3 on t2.c2 = t3.c2; + // We should make sure there is no NOT_NULL flag in `t2.c1`. + for i, cond := range alignedEQConds { + newCond, _ := alignNotNullWithSchema(cond, join.Schema()) + alignedEQConds[i] = newCond.(*expression.ScalarFunction) + } + alignedNonEQConds := make([]expression.Expression, len(e.nonEQConds)) + for i, cond := range e.nonEQConds { + alignedNonEQConds[i], _ = alignNotNullWithSchema(cond, join.Schema()) + } + join.EqualConditions = alignedEQConds + for _, cond := range alignedNonEQConds { + fromLeft := expression.ExprFromSchema(cond, left.Schema()) + fromRight := expression.ExprFromSchema(cond, right.Schema()) + if fromLeft && !fromRight { + join.LeftConditions = append(join.LeftConditions, cond) + } else if !fromLeft && fromRight { + join.RightConditions = append(join.RightConditions, cond) + } else { + join.OtherConditions = append(join.OtherConditions, cond) + } + } + return join, nil +} + +// alignNotNullWithSchema update the columns in expression with the one from schema, +// whose NOT_NULL flag has already been updated by LogicalJoin.MergeSchema(). +func alignNotNullWithSchema(expr expression.Expression, schema *expression.Schema) (expression.Expression, bool) { + if schema == nil || expr == nil { + return expr, false + } + tryUpdateNotNullFlag := func(dstCol, srcCol *expression.Column) (*expression.Column, bool) { + srcNotNullFlag := mysql.HasNotNullFlag(srcCol.RetType.GetFlag()) + dstNotNullFlag := mysql.HasNotNullFlag(dstCol.RetType.GetFlag()) + if srcNotNullFlag != dstNotNullFlag { + newTp := dstCol.RetType.DeepCopy() + // Make sure NOT_NULL flag of dstCol be same with srcCol. + if srcNotNullFlag { + newTp.AddFlag(mysql.NotNullFlag) + } else { + newTp.DelFlag(mysql.NotNullFlag) + } + newCol := dstCol.Clone().(*expression.Column) + newCol.RetType = newTp + return newCol, true + } + return dstCol, false + } + switch e := expr.(type) { + case *expression.Column: + if schemaCol := schema.RetrieveColumn(e); schemaCol != nil { + return tryUpdateNotNullFlag(e, schemaCol) + } + return e, false + case *expression.CorrelatedColumn: + if schemaCol := schema.RetrieveColumn(&e.Column); schemaCol != nil { + if newCol, updated := tryUpdateNotNullFlag(&e.Column, schemaCol); updated { + clone := e.Clone().(*expression.CorrelatedColumn) + clone.Column = *newCol + return clone, true + } + } + return e, false + case *expression.ScalarFunction: + var needClone bool + newArgs := slices.Clone(e.GetArgs()) + for i, arg := range newArgs { + if newArg, updated := alignNotNullWithSchema(arg, schema); updated { + newArgs[i] = newArg + needClone = true + } + } + if needClone { + clone := e.Clone().(*expression.ScalarFunction) + for i, arg := range newArgs { + clone.GetArgs()[i] = arg + } + return clone, true + } + return e, false + default: + return expr, false + } +} + +func makeInnerJoin(ctx base.PlanContext, checkResult *CheckConnectionResult, existingJoin *logicalop.LogicalJoin, vertexHints map[int]*JoinMethodHint) (base.LogicalPlan, error) { + if existingJoin != nil { + // Append selections to existing join. + // For example: (R1 LEFT JOIN R2 ON R1.c1 = R2.c1) INNER JOIN R3 ON R2.c2 = R3.c2 and (R1.c3 = R2.c3 and R1.c4 IS NULL) + // there will be two edges for R1 and R2, one is R1.c1 = R2.c1, the other is R1.c3 = R2.c3 and R1.c4 IS NULL, + // the second edge is a INNER JOIN edge, and we will append it as selection to the first LEFT JOIN edge. + condCap := 0 + for _, e := range checkResult.appliedInnerEdges { + condCap += len(e.eqConds) + len(e.nonEQConds) + } + selection := logicalop.LogicalSelection{ + Conditions: make([]expression.Expression, 0, condCap), + } + for _, e := range checkResult.appliedInnerEdges { + eqExprs := expression.ScalarFuncs2Exprs(e.eqConds) + selection.Conditions = append(selection.Conditions, eqExprs...) + selection.Conditions = append(selection.Conditions, e.nonEQConds...) + } + resSelection := selection.Init(ctx, existingJoin.QueryBlockOffset()) + resSelection.SetChildren(existingJoin) + return resSelection, nil + } + + var err error + var alignedEQConds []*expression.ScalarFunction + newEqConds := make([]*expression.ScalarFunction, 0, 8) + newOtherConds := make([]expression.Expression, 0, 8) + for _, e := range checkResult.appliedInnerEdges { + checkResult.node1.p, checkResult.node2.p, alignedEQConds, err = alignEQConds(ctx, checkResult.node1.p, checkResult.node2.p, e.eqConds) + if err != nil { + return nil, err + } + newEqConds = append(newEqConds, alignedEQConds...) + newOtherConds = append(newOtherConds, e.nonEQConds...) + } + join, err := newCartesianJoin(ctx, checkResult.appliedInnerEdges[0].joinType, checkResult.node1.p, checkResult.node2.p, vertexHints) + if err != nil { + return nil, err + } + join.EqualConditions = append(join.EqualConditions, newEqConds...) + join.OtherConditions = append(join.OtherConditions, newOtherConds...) + + return join, nil +} + +func newCartesianJoin(ctx base.PlanContext, joinType base.JoinType, left, right base.LogicalPlan, vertexHints map[int]*JoinMethodHint) (*logicalop.LogicalJoin, error) { + offset := left.QueryBlockOffset() + if offset != right.QueryBlockOffset() { + offset = -1 + } + + join := logicalop.LogicalJoin{ + JoinType: joinType, + Reordered: true, + }.Init(ctx, offset) + join.SetSchema(expression.MergeSchema(left.Schema(), right.Schema())) + join.SetChildren(left, right) + join.MergeSchema() + SetNewJoinWithHint(join, vertexHints) + return join, nil +} + +// HasRemainingEdges checks if there are remaining edges not in usedEdges. +func (d *ConflictDetector) HasRemainingEdges(usedEdges map[uint64]struct{}) (remaining bool) { + d.iterateEdges(func(e *edge) bool { + if len(e.eqConds) > 0 || len(e.nonEQConds) > 0 { + if _, ok := usedEdges[e.idx]; !ok { + remaining = true + return false + } + } + return true + }) + return +} + +// ruleTableEntry encodes whether a given algebraic property holds for a pair of +// join types (see Table 2 and Table 3 in the paper): +// +// 0 — property does NOT hold; a conflict rule must be generated. +// 1 — property holds unconditionally. +// 2 — property holds only when the null-rejection condition is satisfied. +// +// Currently, value 2 is unused because: +// 1. TiDB does not support FULL OUTER JOIN, which is the main source of +// conditional entries in the paper's tables. +// 2. extractJoinGroup() only admits non-inner joins that have at least one +// equi-condition, which implicitly guarantees null-rejection on both sides. +// This allows assoc(LEFT, LEFT) and assoc(RIGHT, RIGHT) to be treated as +// unconditional (value 1). If non-inner joins without equi-conditions are +// admitted in the future, null-rejection checks must be added here. +// +// The value 2 is retained as a placeholder for future extension. +type ruleTableEntry int + +// assocRuleTable[e1][e2] indicates whether the associativity transformation +// +// (R1 ⋈_e1 R2) ⋈_e2 R3 ⟺ R1 ⋈_e1 (R2 ⋈_e2 R3) +// +// is valid for the given pair of join types. +// Rows = join type of e1 (left/child edge), Columns = join type of e2 (right/parent edge). +var assocRuleTable = [][]ruleTableEntry{ + // INNER LEFT RIGHT SEMI ANTI + /* INNER */ {1, 1, 0, 1, 1}, + /* LEFT */ {0, 1, 0, 0, 0}, // assoc(LEFT,LEFT)=1: see NOTE above. + /* RIGHT */ {1, 1, 1, 1, 1}, // assoc(RIGHT,RIGHT)=1: see NOTE above. + /* SEMI */ {0, 0, 0, 0, 0}, + /* ANTI */ {0, 0, 0, 0, 0}, +} + +// leftAsscomRuleTable[e1][e2] indicates whether the left-asscom transformation +// +// (R1 ⋈_e1 R2) ⋈_e2 R3 ⟺ (R1 ⋈_e2 R3) ⋈_e1 R2 +// +// is valid. Here e1 is the child edge (in leftEdges) and e2 is the parent edge. +var leftAsscomRuleTable = [][]ruleTableEntry{ + // INNER LEFT RIGHT SEMI ANTI + /* INNER */ {1, 1, 0, 1, 1}, + /* LEFT */ {1, 1, 1, 1, 1}, // l-asscom(LEFT, RIGHT)=1; see NOTE above. + /* RIGHT */ {0, 1, 0, 0, 0}, // l-asscom(RIGHT, LEFT)=1; see NOTE above. + /* SEMI */ {1, 1, 0, 1, 1}, + /* ANTI */ {1, 1, 0, 1, 1}, +} + +// rightAsscomRuleTable[e1][e2] indicates whether the right-asscom transformation +// +// R1 ⋈_e1 (R2 ⋈_e2 R3) ⟺ R2 ⋈_e2 (R1 ⋈_e1 R3) +// +// is valid. Here e1 is the parent edge and e2 is the child edge (in rightEdges). +var rightAsscomRuleTable = [][]ruleTableEntry{ + // INNER LEFT RIGHT SEMI ANTI + /* INNER */ {1, 0, 1, 0, 0}, + /* LEFT */ {0, 0, 1, 0, 0}, // r-asscom(LEFT, RIGHT)=1; see NOTE above. + /* RIGHT */ {1, 1, 1, 0, 0}, // r-asscom(RIGHT, LEFT)=1; see NOTE above. + /* SEMI */ {0, 0, 0, 0, 0}, + /* ANTI */ {0, 0, 0, 0, 0}, +} diff --git a/pkg/planner/core/joinorder/join_order.go b/pkg/planner/core/joinorder/join_order.go new file mode 100644 index 0000000000000..388eebb5c6cc3 --- /dev/null +++ b/pkg/planner/core/joinorder/join_order.go @@ -0,0 +1,645 @@ +// Copyright 2026 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package joinorder + +import ( + "cmp" + "fmt" + "maps" + "slices" + "strings" + + "github.com/cockroachdb/errors" + "github.com/pingcap/tidb/pkg/expression" + "github.com/pingcap/tidb/pkg/parser/ast" + "github.com/pingcap/tidb/pkg/planner/core/base" + "github.com/pingcap/tidb/pkg/planner/core/operator/logicalop" + "github.com/pingcap/tidb/pkg/util/hint" + "github.com/pingcap/tidb/pkg/util/intest" + "github.com/pingcap/tidb/pkg/util/logutil" + "go.uber.org/zap" +) + +// JoinOrder is the base struct for join order optimization. +type JoinOrder struct { + ctx base.PlanContext + group *joinGroup +} + +// A joinGroup is a subtree of the original plan tree. It's the unit for join order. +// root is the root of the subtree, if root is not a join, then the joinGroup only contains one vertex. +// vertexes are the leaf nodes of the subtree, it may have its children, but they are considered as a vertex in this subtree. +type joinGroup struct { + root base.LogicalPlan + // All vertexes in this join group. + // A vertex means a leaf node in this join group tree, + // it may have its own children, but they are considered as a single unit in this join group. + vertexes []base.LogicalPlan + + // All leading hints for this join group. + leadingHints []*hint.PlanHints + // Whether this join group contains any user-provided LEADING hint. Internal + // ordered-leading preferences reuse the same builder path but should not emit + // user-facing hint warnings. + hasUserLeadingHint bool + // Join method hints for each vertex in this join group. + // Key is the planID of the vertex. + // This is for restore join method hints after join reorder. + vertexHints map[int]*JoinMethodHint + + // There is no need to check ConflictRules if all joins in this group are inner join. + // This can speed up the join reorder process. + allInnerJoin bool + + // selConds holds filter conditions collected from Selection operators + // that were looked through during extractJoinGroup. + selConds map[int][]expression.Expression +} + +func (g *joinGroup) merge(other *joinGroup) { + g.vertexes = append(g.vertexes, other.vertexes...) + g.leadingHints = append(g.leadingHints, other.leadingHints...) + g.hasUserLeadingHint = g.hasUserLeadingHint || other.hasUserLeadingHint + if len(other.vertexHints) > 0 { + if g.vertexHints == nil { + g.vertexHints = make(map[int]*JoinMethodHint, len(other.vertexHints)) + } + maps.Copy(g.vertexHints, other.vertexHints) + } + g.allInnerJoin = g.allInnerJoin && other.allInnerJoin + + if len(other.selConds) > 0 { + if g.selConds == nil { + g.selConds = make(map[int][]expression.Expression, len(other.selConds)) + } + maps.Copy(g.selConds, other.selConds) + } +} + +func extractJoinGroup(p base.LogicalPlan) (resJoinGroup *joinGroup) { + if sel, isSel := p.(*logicalop.LogicalSelection); isSel { + if p.SCtx().GetSessionVars().TiDBOptJoinReorderThroughSel && + !slices.ContainsFunc(sel.Conditions, expression.IsMutableEffectsExpr) { + childGroup := extractJoinGroup(sel.Children()[0]) + // This check is necessary: the child JoinGroup must contain at least one join operator. + // If a table outside the Selection subtree needs to be reordered with tables inside it, + // the connectivity must be verified through CR. Since the CR of Selection-derived edge will not be generated, + // so we need rely on CRs of joins in Selection's subtree. + if len(childGroup.vertexes) > 1 { + if childGroup.selConds == nil { + childGroup.selConds = make(map[int][]expression.Expression) + } + childGroup.selConds[sel.ID()] = sel.Conditions + childGroup.root = sel + return childGroup + } + } + return makeSingleGroup(p) + } + + join, isJoin := p.(*logicalop.LogicalJoin) + if !isJoin { + return makeSingleGroup(p) + } + + var curLeadingHint *hint.PlanHints + var curLeadingHintFromUser bool + if join.PreferJoinOrder { + curLeadingHint = join.HintInfo + curLeadingHintFromUser = true + } else if join.InternalPreferJoinOrder { + curLeadingHint = join.InternalHintInfo + } + defer func() { + if curLeadingHint != nil { + resJoinGroup.leadingHints = append(resJoinGroup.leadingHints, curLeadingHint) + resJoinGroup.hasUserLeadingHint = resJoinGroup.hasUserLeadingHint || curLeadingHintFromUser + } + }() + + if join.StraightJoin { + return makeSingleGroup(p) + } + + // For now, we only handle inner join and left/right outer join. + if join.JoinType != base.InnerJoin && join.JoinType != base.LeftOuterJoin && join.JoinType != base.RightOuterJoin { + return makeSingleGroup(p) + } + + if !p.SCtx().GetSessionVars().EnableOuterJoinReorder && (join.JoinType == base.LeftOuterJoin || join.JoinType == base.RightOuterJoin) { + return makeSingleGroup(p) + } + + if join.PreferJoinType > uint(0) && !p.SCtx().GetSessionVars().EnableAdvancedJoinHint { + return makeSingleGroup(p) + } + + if slices.ContainsFunc(join.EqualConditions, func(expr *expression.ScalarFunction) bool { + return expr.FuncName.L == ast.NullEQ + }) { + return makeSingleGroup(p) + } + + // Due to the limited search space of the greedy algorithm and our currently rudimentary cost model, suboptimal join orders may occasionally be generated. + // For example: + // Original Order: (R1 INNER R2 ON P12) LEFT JOIN (R3 INNER R4 ON P34) ON P23 (Pxy denotes a join condition using Rx and Ry as inputs.) + // The LEFT JOIN condition P23 contains only otherCond (non-equi conditions) without any eqCond. + // Potential Suboptimal Order: R1 INNER (R2 LEFT JOIN (R3 INNER R4 ON P34) ON P23) ON P12 + // This implies that the edge P23 (lacking an eqCond) is applied earlier than in the original order. + // Since edges without equi-conditions perform poorly (as the executor cannot utilize Hash Join), + // and the current single-sequence greedy algorithm cannot explore enough alternative sequences, it may return this poor-performing order directly. + // So We have temporarily disabled reordering for non INNER JOIN that without eqCond. + // For INNER JOINs, we introduced a penalty factor. If the factor is set less equal to 0, + // Cartesian products will only be applied at the final step(which will generate a bushy tree). + // + // Also we allow both assoc(left, left) and assoc(right, right) without considering null-rejective property, + // Because for NON-INNER JOIN with eqCond, it must be null-rejective on both sides. + // If we support reorder NON-INNER JOIN without eqCond in the future, we need to consider null-rejective property here. + // See assocRuleTable in conflict_detector.go for more details. + if join.JoinType != base.InnerJoin && len(join.EqualConditions) == 0 { + return makeSingleGroup(p) + } + + var leftHasHint, rightHasHint bool + var vertexHints map[int]*JoinMethodHint + if p.SCtx().GetSessionVars().EnableAdvancedJoinHint && join.PreferJoinType > uint(0) { + vertexHints = make(map[int]*JoinMethodHint) + if join.LeftPreferJoinType > uint(0) { + vertexHints[join.Children()[0].ID()] = &JoinMethodHint{ + PreferJoinMethod: join.LeftPreferJoinType, + HintInfo: join.HintInfo, + } + leftHasHint = true + } + if join.RightPreferJoinType > uint(0) { + vertexHints[join.Children()[1].ID()] = &JoinMethodHint{ + PreferJoinMethod: join.RightPreferJoinType, + HintInfo: join.HintInfo, + } + rightHasHint = true + } + } + + resJoinGroup = &joinGroup{ + root: p, + vertexes: []base.LogicalPlan{}, + vertexHints: vertexHints, + allInnerJoin: join.JoinType == base.InnerJoin, + } + + leftShouldPreserve := curLeadingHint != nil && IsDerivedTableInLeadingHint(join.Children()[0], curLeadingHint) + var leftJoinGroup, rightJoinGroup *joinGroup + if !leftHasHint && !leftShouldPreserve { + leftJoinGroup = extractJoinGroup(join.Children()[0]) + } else { + leftJoinGroup = makeSingleGroup(join.Children()[0]) + } + resJoinGroup.merge(leftJoinGroup) + + rightShouldPreserve := curLeadingHint != nil && IsDerivedTableInLeadingHint(join.Children()[1], curLeadingHint) + if !rightHasHint && !rightShouldPreserve { + rightJoinGroup = extractJoinGroup(join.Children()[1]) + } else { + rightJoinGroup = makeSingleGroup(join.Children()[1]) + } + resJoinGroup.merge(rightJoinGroup) + return resJoinGroup +} + +func makeSingleGroup(p base.LogicalPlan) *joinGroup { + return &joinGroup{ + root: p, + vertexes: []base.LogicalPlan{p}, + allInnerJoin: true, + } +} + +// Optimize performs join order optimization on the given plan. +func Optimize(p base.LogicalPlan) (base.LogicalPlan, error) { + return optimizeRecursive(p) +} + +func optimizeRecursive(p base.LogicalPlan) (base.LogicalPlan, error) { + if p == nil { + return nil, nil + } + if _, ok := p.(*logicalop.LogicalCTE); ok { + return p, nil + } + + var err error + joinGroup := extractJoinGroup(p) + if len(joinGroup.vertexes) <= 0 { + return nil, errors.Errorf("join group has no vertexes, p: %v", p) + } + + // Only one vertex, no need to reorder. Only need to optimize its children. + if len(joinGroup.vertexes) == 1 { + newChildren := make([]base.LogicalPlan, 0, len(p.Children())) + for _, child := range p.Children() { + newChild, err := optimizeRecursive(child) + if err != nil { + return nil, err + } + newChildren = append(newChildren, newChild) + } + p.SetChildren(newChildren...) + + if joinGroup.hasUserLeadingHint && len(joinGroup.leadingHints) > 0 { + p.SCtx().GetSessionVars().StmtCtx.SetHintWarning("leading hint is inapplicable, check the join type or the join algorithm hint") + } + return p, nil + } + + // Multiple vertexes, starts to reorder. + vertexMap := make(map[int]base.LogicalPlan, len(joinGroup.vertexes)) + for i, v := range joinGroup.vertexes { + // Make sure the vertexes are all optimized. + oldID := v.ID() + if joinGroup.vertexes[i], err = optimizeRecursive(v); err != nil { + return nil, err + } + vertexMap[oldID] = joinGroup.vertexes[i] + } + if len(vertexMap) > 0 { + joinGroup.root = replaceJoinGroupVertexes(joinGroup.root, vertexMap) + } + if p, err = optimizeForJoinGroup(p.SCtx(), joinGroup); err != nil { + return nil, err + } + return p, nil +} + +// replaceJoinGroupVertexes walks the join-group subtree rooted at `root` and +// swaps every leaf vertex with its optimized replacement from vertexMap. +// +// Why this is needed: each vertex in the join group is recursively optimized +// (optimizeRecursive) before join reorder runs. That optimisation may rebuild +// the plan node (new ID, new children), so the original plan tree still points +// to the stale, pre-optimisation nodes. This function patches the tree so that +// the ConflictDetector.Build(), which traverses from root down to locate +// vertexes by plan ID, sees the up-to-date nodes. +func replaceJoinGroupVertexes(root base.LogicalPlan, vertexMap map[int]base.LogicalPlan) base.LogicalPlan { + if root == nil { + return nil + } + if replacement, ok := vertexMap[root.ID()]; ok { + return replacement + } + children := root.Children() + if len(children) == 0 { + return root + } + newChildren := make([]base.LogicalPlan, len(children)) + for i, child := range children { + newChildren[i] = replaceJoinGroupVertexes(child, vertexMap) + } + root.SetChildren(newChildren...) + return root +} + +func optimizeForJoinGroup(ctx base.PlanContext, group *joinGroup) (p base.LogicalPlan, err error) { + originalSchema := group.root.Schema() + + // TODO impl DP OR merge the old DP impl with the new CD-C impl. + // Make sure there is no behavior change since some users already rely on the old DP impl. + // useGreedy := len(group.vertexes) > ctx.GetSessionVars().TiDBOptJoinReorderThreshold + useGreedy := true + if useGreedy { + joinOrderGreedy := newJoinOrderGreedy(ctx, group) + if p, err = joinOrderGreedy.optimize(); err != nil { + return nil, err + } + } else { + joinOrderDP := newJoinOrderDP(ctx, group) + if p, err = joinOrderDP.optimize(); err != nil { + return nil, err + } + } + + // Ensure the schema is not changed after join reorder. + if !p.Schema().Equal(originalSchema) { + proj := logicalop.LogicalProjection{ + Exprs: expression.Column2Exprs(originalSchema.Columns), + }.Init(p.SCtx(), p.QueryBlockOffset()) + proj.SetSchema(originalSchema.Clone()) + proj.SetChildren(p) + return proj, nil + } + return p, nil +} + +type joinOrderDP struct { + JoinOrder +} + +func newJoinOrderDP(_ base.PlanContext, _ *joinGroup) *joinOrderDP { + panic("not implement yet") +} + +func (*joinOrderDP) optimize() (base.LogicalPlan, error) { + panic("not implement yet") +} + +type joinOrderGreedy struct { + JoinOrder +} + +func newJoinOrderGreedy(ctx base.PlanContext, group *joinGroup) *joinOrderGreedy { + return &joinOrderGreedy{ + JoinOrder: JoinOrder{ + ctx: ctx, + group: group, + }, + } +} + +// buildJoinByHint builds a join tree according to the leading hints. +func (j *joinOrderGreedy) buildJoinByHint(detector *ConflictDetector, nodes []*Node) (*Node, []*Node, error) { + if len(j.group.leadingHints) == 0 { + return nil, nodes, nil + } + + leadingHint, hasDifferent := CheckAndGenerateLeadingHint(j.group.leadingHints) + if hasDifferent && j.group.hasUserLeadingHint { + j.ctx.GetSessionVars().StmtCtx.SetHintWarning( + "We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid") + } + + if leadingHint == nil || leadingHint.LeadingList == nil { + return nil, nodes, nil + } + + findAndRemoveByHint := func(available []*Node, hint *ast.HintTable) (*Node, []*Node, bool) { + return FindAndRemovePlanByAstHint(j.ctx, available, hint, func(node *Node) base.LogicalPlan { + return node.p + }) + } + joiner := func(left, right *Node) (*Node, bool, error) { + _, newNode, err := checkConnectionAndMakeJoin(detector, left, right, j.group.vertexHints, true) + if err != nil { + return nil, false, err + } + if newNode == nil { + return nil, false, nil + } + return newNode, true, nil + } + warn := func() { + if j.group.hasUserLeadingHint { + j.ctx.GetSessionVars().StmtCtx.SetHintWarning("leading hint contains unexpected element type") + } + } + + // BuildLeadingTreeFromList may modify nodes slice, so we need to clone it first. + // And only return the modified nodes(nodesAfterHint) when the leading hint is applicable, + // and original nodes slice will be returned when the leading hint is inapplicable. + nodeWithHint, nodesAfterHint, ok, err := BuildLeadingTreeFromList(leadingHint.LeadingList, slices.Clone(nodes), findAndRemoveByHint, joiner, warn) + if err != nil { + return nil, nil, err + } + if !ok { + if j.group.hasUserLeadingHint { + j.ctx.GetSessionVars().StmtCtx.SetHintWarning("leading hint is inapplicable, check if the leading hint table is valid") + } + return nil, nodes, nil + } + return nodeWithHint, nodesAfterHint, nil +} + +func checkConnectionAndMakeJoin(detector *ConflictDetector, leftPlan, rightPlan *Node, vertexHints map[int]*JoinMethodHint, allowNoEQ bool) (*CheckConnectionResult, *Node, error) { + checkResult, err := detector.CheckConnection(leftPlan, rightPlan) + if err != nil { + return nil, nil, err + } + if !checkResult.Connected() { + if !allowNoEQ { + return nil, nil, nil + } + if checkResult = detector.TryCreateCartesianCheckResult(leftPlan, rightPlan); checkResult == nil { + return nil, nil, nil + } + } + newNode, err := detector.MakeJoin(checkResult, vertexHints) + if err != nil { + return nil, nil, err + } + return checkResult, newNode, nil +} + +func (j *joinOrderGreedy) optimize() (base.LogicalPlan, error) { + group := j.group + detector := newConflictDetector(j.ctx) + nodes, err := detector.Build(group) + if err != nil { + return nil, err + } + nodeWithHint, nodes, err := j.buildJoinByHint(detector, nodes) + if err != nil { + return nil, err + } + if len(nodes) < 1 { + return nodeWithHint.p, nil + } + + slices.SortFunc(nodes, func(a, b *Node) int { + return cmp.Compare(a.cumCost, b.cumCost) + }) + + if nodeWithHint != nil { + newNodes := make([]*Node, 0, len(nodes)+1) + newNodes = append(newNodes, nodeWithHint) + newNodes = append(newNodes, nodes...) + nodes = newNodes + } + + var cartesianFactor float64 = j.ctx.GetSessionVars().CartesianJoinOrderThreshold + var disableCartesian = cartesianFactor <= 0 + allowNoEQ := !disableCartesian && j.group.allInnerJoin + if nodes, err = greedyConnectJoinNodes(detector, nodes, j.group.vertexHints, cartesianFactor, allowNoEQ); err != nil { + return nil, err + } + + usedEdges := collectUsedEdges(nodes) + if !allowNoEQ && detector.HasRemainingEdges(usedEdges) { + // After the first round of greedy connection, there are still some remaining edges, + // for example: R1 INNER JOIN R2 ON R1.c1 < R2.c2 + // the above join can only be connected when non-eq edges are allowed, + // and the first round of greedy enumeration is not allowed to use non-eq edges. + // So we got here and we need to the second round of enumeration with `allowNoEQ` as true. + befLen := len(nodes) + // Clamp to 1 to avoid cumCost*0=0 making non-EQ joins appear free. + if cartesianFactor <= 0 { + cartesianFactor = 1 + } + if nodes, err = greedyConnectJoinNodes(detector, nodes, j.group.vertexHints, cartesianFactor, true); err != nil { + return nil, err + } + if len(nodes) != befLen { + // Only collect usedEdges when new joins are made in the second round. + usedEdges = collectUsedEdges(nodes) + } + } + if detector.HasRemainingEdges(usedEdges) { + totalEdges, usedEdgeCount, missingEdges, missingDetail, nodeSets := summarizeEdges(detector, usedEdges, nodes, 4) + logutil.BgLogger().Warn("join reorder skipped because not all edges are used", + zap.Int("rootID", group.root.ID()), + zap.Int("nodes", len(nodes)), + zap.Int("totalEdges", totalEdges), + zap.Int("usedEdges", usedEdgeCount), + zap.Int("missingEdges", missingEdges), + zap.String("missingDetail", missingDetail), + zap.String("nodeSets", nodeSets), + zap.Bool("allInnerJoin", group.allInnerJoin)) + if intest.InTest { + return nil, errors.New("got remaining edges during join reorder") + } + return group.root, nil + } + if len(nodes) <= 0 { + return nil, errors.New("internal error: bushy join tree nodes is empty") + } + // makeBushyTree connects the remaining nodes into a bushy tree using cartesian joins, + // It handles situations where there is no edges between different subgraphs, + return makeBushyTree(j.ctx, nodes, j.group.vertexHints) +} + +func greedyConnectJoinNodes(detector *ConflictDetector, nodes []*Node, vertexHints map[int]*JoinMethodHint, cartesianFactor float64, allowNoEQ bool) ([]*Node, error) { + // Outer loop: keep trying while we have multiple nodes and made progress in the last iteration. + // This handles cases where conflict rules block some joins until other joins are completed. + for len(nodes) > 1 { + madeProgress := false + var curJoinIdx int + for curJoinIdx < len(nodes)-1 { + var bestNode *Node + var bestIdx int + curJoinTree := nodes[curJoinIdx] + for iterIdx := curJoinIdx + 1; iterIdx < len(nodes); iterIdx++ { + iterNode := nodes[iterIdx] + checkResult, newNode, err := checkConnectionAndMakeJoin(detector, curJoinTree, iterNode, vertexHints, allowNoEQ) + if err != nil { + return nil, err + } + if newNode == nil { + continue + } + if checkResult.NoEQEdge() { + // The original plan tree may have cartesian edges, to avoid cartesian join happens first, + // we need the check here. + if !allowNoEQ { + continue + } + // TODO: Non INNER JOIN without eqCond is not supported for now. + // For INNER JOIN, if cartesianFactor > 0, we apply a penalty to the cost of the newNode, + // and we might generate a tree with cartesian edge. + // For non INNER JOIN, the logic in extractJoinGroup ensures we will not reach here, + // check the comment in extractJoinGroup for more details. + newNode.cumCost = newNode.cumCost * cartesianFactor + } + if bestNode == nil || newNode.cumCost < bestNode.cumCost { + bestNode = newNode + bestIdx = iterIdx + } + } + if bestNode == nil { + curJoinIdx++ + } else { + nodes[curJoinIdx] = bestNode + nodes = append(nodes[:bestIdx], nodes[bestIdx+1:]...) + madeProgress = true + } + } + // If no progress was made in this iteration, we cannot connect any more nodes. + if !madeProgress { + break + } + } + return nodes, nil +} + +func collectUsedEdges(nodes []*Node) map[uint64]struct{} { + usedEdges := make(map[uint64]struct{}) + for _, node := range nodes { + if node != nil && node.usedEdges != nil { + maps.Copy(usedEdges, node.usedEdges) + } + } + return usedEdges +} + +func summarizeEdges(detector *ConflictDetector, usedEdges map[uint64]struct{}, nodes []*Node, limit int) (total, used, missing int, detail, nodeSets string) { + if usedEdges == nil { + usedEdges = make(map[uint64]struct{}) + } + addEdge := func(e *edge, missingList *[]string) { + if len(e.eqConds) == 0 && len(e.nonEQConds) == 0 { + return + } + total++ + if _, ok := usedEdges[e.idx]; ok { + used++ + return + } + missing++ + if len(*missingList) < limit { + *missingList = append(*missingList, fmt.Sprintf("{idx:%d type:%v eq:%d nonEq:%d tes:%v left:%v right:%v}", + e.idx, e.joinType, len(e.eqConds), len(e.nonEQConds), e.tes.String(), e.leftVertexes.String(), e.rightVertexes.String())) + } + } + + var missingList []string + for _, e := range detector.innerEdges { + addEdge(e, &missingList) + } + for _, e := range detector.nonInnerEdges { + addEdge(e, &missingList) + } + if missing > limit { + missingList = append(missingList, fmt.Sprintf("...(+%d more)", missing-limit)) + } + detail = strings.Join(missingList, ", ") + + if len(nodes) > 0 { + nodeBits := make([]string, 0, len(nodes)) + for _, n := range nodes { + if n == nil { + continue + } + nodeBits = append(nodeBits, n.bitSet.String()) + } + nodeSets = strings.Join(nodeBits, ",") + } + return total, used, missing, detail, nodeSets +} + +func makeBushyTree(ctx base.PlanContext, cartesianNodes []*Node, vertexHints map[int]*JoinMethodHint) (base.LogicalPlan, error) { + var iterNodes []*Node + for len(cartesianNodes) > 1 { + for i := 0; i < len(cartesianNodes); i += 2 { + if i+1 >= len(cartesianNodes) { + iterNodes = append(iterNodes, cartesianNodes[i]) + break + } + newJoin, err := newCartesianJoin(ctx, base.InnerJoin, cartesianNodes[i].p, cartesianNodes[i+1].p, vertexHints) + if err != nil { + return nil, err + } + iterNodes = append(iterNodes, &Node{p: newJoin}) + } + cartesianNodes = iterNodes + iterNodes = iterNodes[:0] + } + return cartesianNodes[0].p, nil +} diff --git a/pkg/planner/core/joinorder/ordered_leading.go b/pkg/planner/core/joinorder/ordered_leading.go new file mode 100644 index 0000000000000..b377c5f712f03 --- /dev/null +++ b/pkg/planner/core/joinorder/ordered_leading.go @@ -0,0 +1,383 @@ +// Copyright 2026 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package joinorder + +import ( + "slices" + + "github.com/pingcap/tidb/pkg/expression" + "github.com/pingcap/tidb/pkg/meta/model" + "github.com/pingcap/tidb/pkg/parser/ast" + "github.com/pingcap/tidb/pkg/planner/core/base" + "github.com/pingcap/tidb/pkg/planner/core/operator/logicalop" + "github.com/pingcap/tidb/pkg/planner/util" + "github.com/pingcap/tidb/pkg/util/hint" +) + +// OrderedLeadingChoice records the vertex that carries the ordering requirement +// within the current join group and, when possible, the single-table identity +// that can be bridged into an internal LEADING hint on the group's anchor join. +type OrderedLeadingChoice struct { + CarrierVertex base.LogicalPlan + LeadingTable *hint.HintedTable + Vertices []base.LogicalPlan +} + +// FindOrderedLeadingChoice returns the vertex that should keep carrying the +// current ordering requirement inside this join group. The actual question of +// whether that vertex's subtree can really preserve the order is handled by the +// recursive caller. +func FindOrderedLeadingChoice(root base.LogicalPlan, orderingCols []*expression.Column) *OrderedLeadingChoice { + if root == nil || len(orderingCols) == 0 { + return nil + } + + group := extractJoinGroup(root) + if len(group.vertexes) <= 1 { + return nil + } + + return findOrderedLeadingChoice(group, orderingCols) +} + +// TryAnnotateOrderedLeading attaches an internal LEADING preference to the top +// join of the current join group once the chosen carrier vertex has already +// proven, through recursive exploration, that its subtree can satisfy the +// ordering requirement. +func TryAnnotateOrderedLeading(root base.LogicalPlan, choice *OrderedLeadingChoice) bool { + if root == nil || choice == nil { + return false + } + + group := extractJoinGroup(root) + anchor := findLeadingHintAnchor(group.root) + if len(group.leadingHints) > 0 || anchor == nil || anchor.PreferJoinOrder || anchor.InternalPreferJoinOrder || + anchor.PreferJoinType > 0 || anchor.HintInfo != nil || anchor.InternalHintInfo != nil || choice.LeadingTable == nil { + return false + } + + // Record the ordered-leading choice separately from user hints so downstream + // warning paths can keep treating user-provided LEADING differently from this + // synthesized preference. + anchor.InternalPreferJoinOrder = true + anchor.InternalHintInfo = buildSingleTableLeadingHint(choice.LeadingTable) + return true +} + +// findLeadingHintAnchor returns the top join that should receive the internal +// LEADING hint for the current join group. The group root may be wrapped by a +// Selection because TiDB can keep a pushed-down filter above a reorderable join +// group, so we skip such wrappers and stop once the tree shape is no longer +// "Selection -> Join". +func findLeadingHintAnchor(root base.LogicalPlan) *logicalop.LogicalJoin { + for root != nil { + switch node := root.(type) { + case *logicalop.LogicalJoin: + return node + case *logicalop.LogicalSelection: + if len(node.Children()) == 0 { + return nil + } + root = node.Children()[0] + default: + return nil + } + } + return nil +} + +func buildSingleTableLeadingHint(table *hint.HintedTable) *hint.PlanHints { + if table == nil { + return nil + } + qbName := ast.CIStr{} + if table.SelectOffset > 0 { + if generatedQBName, err := hint.GenerateQBName(hint.TypeSelect, table.SelectOffset); err == nil { + qbName = generatedQBName + } + } + return &hint.PlanHints{ + LeadingJoinOrder: []hint.HintedTable{*table}, + LeadingList: &ast.LeadingList{ + Items: []any{ + &ast.HintTable{ + DBName: table.DBName, + TableName: table.TblName, + QBName: qbName, + }, + }, + }, + } +} + +// findOrderedLeadingChoice picks one vertex that should keep carrying the +// ordering requirement inside the current join group. Each ordering vector must +// still belong to one vertex as a whole instead of column-by-column. For +// example, if the join group is {t1, t2, t3} and the required order is +// (t2.a, t2.b), we only pick a vertex whose schema contains both columns. The +// recursive caller will then keep exploring that vertex's subtree to prove +// whether the order can really be preserved. If the chosen vertex can also be +// represented as a single hinted table, we additionally return the bridged +// LEADING target for the current anchor join. +func findOrderedLeadingChoice(group *joinGroup, orderingCols []*expression.Column) *OrderedLeadingChoice { + _, orderingColUniqueIDs := normalizeOrderingColumns(orderingCols) + if len(orderingColUniqueIDs) == 0 || len(orderingColUniqueIDs) != len(orderingCols) { + return nil + } + for _, vertex := range group.vertexes { + if !schemaContainsAllOrderingColumns(vertex, orderingColUniqueIDs) { + continue + } + choice := &OrderedLeadingChoice{CarrierVertex: vertex} + // The candidate may still be rejected by the caller if the current group + // cannot bridge it into a single-table internal LEADING hint. + choice.LeadingTable = util.ExtractTableAlias(vertex, vertex.QueryBlockOffset()) + choice.Vertices = group.vertexes + return choice + } + return nil +} + +// normalizeOrderingColumns validates the ordering columns and extracts their IDs and UniqueIDs. +func normalizeOrderingColumns(orderingCols []*expression.Column) ([]int64, map[int64]struct{}) { + orderingColIDs := make([]int64, 0, len(orderingCols)) + orderingColUniqueIDs := make(map[int64]struct{}, len(orderingCols)) + for _, col := range orderingCols { + if col == nil || col.ID <= 0 || col.UniqueID <= 0 { + return nil, nil + } + orderingColIDs = append(orderingColIDs, col.ID) + orderingColUniqueIDs[col.UniqueID] = struct{}{} + } + return orderingColIDs, orderingColUniqueIDs +} + +func schemaContainsAllOrderingColumns(plan base.LogicalPlan, orderingColUniqueIDs map[int64]struct{}) bool { + if len(orderingColUniqueIDs) == 0 { + return false + } + schema := plan.Schema() + if schema == nil || len(schema.Columns) < len(orderingColUniqueIDs) { + return false + } + matched := 0 + for _, col := range schema.Columns { + if _, ok := orderingColUniqueIDs[col.UniqueID]; ok { + matched++ + } + } + return matched == len(orderingColUniqueIDs) +} + +// DsSatisfiesOrdering proves that the chosen DataSource can provide the +// requested ordering locally after the order-aware rule has recursively +// descended to the carrier leaf. +func DsSatisfiesOrdering( + ds *logicalop.DataSource, + orderingCols []*expression.Column, + parentFilters []expression.Expression, +) bool { + if ds == nil { + return false + } + orderingColIDs, orderingColUniqueIDs := normalizeOrderingColumns(orderingCols) + if len(orderingColIDs) == 0 || len(orderingColIDs) != len(orderingCols) { + return false + } + if !schemaContainsAllOrderingColumns(ds, orderingColUniqueIDs) { + return false + } + return tableHasIndexMatchingOrdering(ds, orderingColIDs, nil, parentFilters) +} + +func tableHasIndexMatchingOrdering( + ds *logicalop.DataSource, + orderingColIDs []int64, + groupSelectionConds []expression.Expression, + parentFilters []expression.Expression, +) bool { + if ds == nil { + return false + } + + // parentFilters carries deterministic single-table predicates collected from + // ancestors outside the current join group. They matter because they can fix + // leading index columns even when the ORDER BY itself only mentions a suffix. + // Example: + // where t.category = 'hot' order by t.id + // can still use index(category, id) to preserve the order of t.id. + equalityColIDs := collectEqualityPredicateColumnIDs(ds, groupSelectionConds, parentFilters) + for _, idx := range ds.TableInfo.Indices { + if idx.State != model.StatePublic || idx.Invisible { + continue + } + if indexMatchesOrdering(idx, ds, orderingColIDs, equalityColIDs) { + return true + } + } + return false +} + +func indexMatchesOrdering( + idx *model.IndexInfo, + ds *logicalop.DataSource, + orderingColIDs []int64, + equalityColIDs map[int64]struct{}, +) bool { + if len(orderingColIDs) == 0 { + return false + } + orderPos := 0 + for _, idxCol := range idx.Columns { + if idxCol.Offset >= len(ds.TableInfo.Columns) { + return false + } + colID := ds.TableInfo.Columns[idxCol.Offset].ID + if orderPos < len(orderingColIDs) && colID == orderingColIDs[orderPos] { + orderPos++ + if orderPos == len(orderingColIDs) { + return true + } + continue + } + if orderPos == 0 { + // Equality predicates let us skip unmatched index-prefix columns before + // we consume the first ORDER BY column. Example: + // index(category, id) + // where category = 'hot' + // order by id + // The category prefix is fixed to one value, so scanning the remaining + // suffix still preserves the order of id. Once we have started matching + // ORDER BY columns, any mismatch breaks the required order. + if _, ok := equalityColIDs[colID]; ok { + continue + } + } + return false + } + return orderPos == len(orderingColIDs) +} + +func collectEqualityPredicateColumnIDs( + plan base.LogicalPlan, + groupSelectionConds []expression.Expression, + parentFilters []expression.Expression, +) map[int64]struct{} { + result := make(map[int64]struct{}) + collectPlanLocalEqualityPredicateColumnIDs(plan, result) + + schema := plan.Schema() + if schema == nil { + return result + } + // The join-group Selection conditions and ancestor filters are both optional + // sources of single-table equalities. We only keep predicates whose columns + // all belong to the current vertex, so passing ancestor filters to child + // groups is safe even when those filters mention other tables. + addEqualityColumnsFromLocalConds(result, schema, groupSelectionConds) + addEqualityColumnsFromLocalConds(result, schema, parentFilters) + return result +} + +func collectPlanLocalEqualityPredicateColumnIDs(plan base.LogicalPlan, result map[int64]struct{}) { + switch node := plan.(type) { + case *logicalop.LogicalSelection: + for _, cond := range node.Conditions { + extractEqualityColumns(cond, result) + } + case *logicalop.DataSource: + for _, cond := range node.AllConds { + extractEqualityColumns(cond, result) + } + } + for _, child := range plan.Children() { + collectPlanLocalEqualityPredicateColumnIDs(child, result) + } +} + +func addEqualityColumnsFromLocalConds(result map[int64]struct{}, schema *expression.Schema, conds []expression.Expression) { + for _, cond := range conds { + if !condBelongsToSchema(cond, schema) { + continue + } + extractEqualityColumns(cond, result) + } +} + +func condBelongsToSchema(cond expression.Expression, schema *expression.Schema) bool { + if cond == nil || schema == nil { + return false + } + cols := expression.ExtractColumns(cond) + if len(cols) == 0 { + return false + } + return slices.IndexFunc(cols, func(col *expression.Column) bool { + return !schema.Contains(col) + }) < 0 +} + +func extractEqualityColumns(expr expression.Expression, result map[int64]struct{}) { + sf, ok := expr.(*expression.ScalarFunction) + if !ok { + return + } + + switch sf.FuncName.L { + case ast.LogicAnd: + for _, arg := range sf.GetArgs() { + extractEqualityColumns(arg, result) + } + return + case ast.EQ: + if len(sf.GetArgs()) != 2 { + return + } + // We only treat const equalities as index-prefix eliminators. For + // example, index(category, id) can satisfy "where category = 'hot' + // order by id". Keeping this conservative EQ-to-const case still helps + // TP-style queries without pulling in general column-equivalence + // reasoning such as inferring order from "a = b". + col, ok := sf.GetArgs()[0].(*expression.Column) + if ok && isDeterministicConstExpr(sf.GetArgs()[1]) && col.ID > 0 { + result[col.ID] = struct{}{} + } + col, ok = sf.GetArgs()[1].(*expression.Column) + if ok && isDeterministicConstExpr(sf.GetArgs()[0]) && col.ID > 0 { + result[col.ID] = struct{}{} + } + return + case ast.In: + args := sf.GetArgs() + // Only singleton IN behaves like a fixed prefix here. Multi-value IN still + // scans multiple point ranges on the leading index column, which does not + // preserve the global order of later index columns. + if len(args) != 2 { + return + } + col, ok := args[0].(*expression.Column) + if !ok || col.ID <= 0 { + return + } + if !isDeterministicConstExpr(args[1]) { + return + } + result[col.ID] = struct{}{} + } +} + +func isDeterministicConstExpr(expr expression.Expression) bool { + return len(expression.ExtractColumns(expr)) == 0 && !expression.IsMutableEffectsExpr(expr) +} diff --git a/pkg/planner/core/logical_plan_builder.go b/pkg/planner/core/logical_plan_builder.go index 101aba1f05684..ebcfc10b84153 100644 --- a/pkg/planner/core/logical_plan_builder.go +++ b/pkg/planner/core/logical_plan_builder.go @@ -3676,7 +3676,7 @@ func (b *PlanBuilder) addAliasName(ctx context.Context, selectStmt *ast.SelectSt } func (b *PlanBuilder) pushTableHints(hints []*ast.TableOptimizerHint, currentLevel int) { - hints = b.hintProcessor.GetCurrentStmtHints(hints, currentLevel) + hints = b.hintProcessor.GetCurrentStmtHints(hints, currentLevel, b.hintState) sessionVars := b.ctx.GetSessionVars() currentDB := sessionVars.CurrentDB warnHandler := sessionVars.StmtCtx @@ -4486,7 +4486,7 @@ func (b *PlanBuilder) buildDataSource(ctx context.Context, tn *ast.TableName, as // Because of the nested views, so we should check the left table list in hint when build the data source from the view inside the current view. currentQBNameMap4View[qbName] = viewQBNameHintTable[1:] currentViewHints[qbName] = b.hintProcessor.ViewQBNameToHints[qbName] - b.hintProcessor.ViewQBNameUsed[qbName] = struct{}{} + b.hintProcessor.MarkViewQBNameUsed(qbName, b.hintState) } } return b.BuildDataSourceFromView(ctx, dbName, tableInfo, currentQBNameMap4View, currentViewHints) @@ -4987,18 +4987,21 @@ func (b *PlanBuilder) BuildDataSourceFromView(ctx context.Context, dbName ast.CI hintProcessor.ViewQBNameToTable = qbNameMap4View hintProcessor.ViewQBNameToHints = viewHints - hintProcessor.ViewQBNameUsed = make(map[string]struct{}) - hintProcessor.QBOffsetToHints = currentQbHints hintProcessor.QBNameToSelOffset = currentQbNameMap + hintState := hintProcessor.NewBuildState() + hintState.QBOffsetToHints = currentQbHints originHintProcessor := b.hintProcessor + originHintState := b.hintState originPlannerSelectBlockAsName := b.ctx.GetSessionVars().PlannerSelectBlockAsName.Load() b.hintProcessor = hintProcessor + b.hintState = hintState newPlannerSelectBlockAsName := make([]ast.HintTable, hintProcessor.MaxSelectStmtOffset()+1) b.ctx.GetSessionVars().PlannerSelectBlockAsName.Store(&newPlannerSelectBlockAsName) defer func() { - b.hintProcessor.HandleUnusedViewHints() + b.hintProcessor.SetWarns(b.hintProcessor.HandleUnusedViewHints(b.hintState, nil)) b.hintProcessor = originHintProcessor + b.hintState = originHintState b.ctx.GetSessionVars().PlannerSelectBlockAsName.Store(originPlannerSelectBlockAsName) }() nodeW := resolve.NewNodeWWithCtx(selectNode, b.resolveCtx) diff --git a/pkg/planner/core/operator/logicalop/logical_datasource.go b/pkg/planner/core/operator/logicalop/logical_datasource.go index 37f46368fea40..c81083c1466d7 100644 --- a/pkg/planner/core/operator/logicalop/logical_datasource.go +++ b/pkg/planner/core/operator/logicalop/logical_datasource.go @@ -675,10 +675,10 @@ func (ds *DataSource) analyzeTiCIIndex() error { continue } if reason := expression.DiagnoseUnmatchedFTSIndexReason(cond, regularFulltextCols, hybridFulltextCols); reason != "" { - return errors.New(reason) + return &base.FTSLikeFallbackError{Cause: errors.New(reason)} } } - return errors.New("Full text search can only be used with a matching fulltext index or you write it in a wrong way") + return &base.FTSLikeFallbackError{Cause: errors.New("Full text search can only be used with a matching fulltext index or you write it in a wrong way")} } if matchedIdx == nil { diff --git a/pkg/planner/core/operator/logicalop/logical_join.go b/pkg/planner/core/operator/logicalop/logical_join.go index 73f50e140284f..ebf4bde62ae01 100644 --- a/pkg/planner/core/operator/logicalop/logical_join.go +++ b/pkg/planner/core/operator/logicalop/logical_join.go @@ -52,11 +52,15 @@ type LogicalJoin struct { StraightJoin bool // HintInfo stores the join algorithm hint information specified by client. - HintInfo *utilhint.PlanHints - PreferJoinType uint - PreferJoinOrder bool - LeftPreferJoinType uint - RightPreferJoinType uint + HintInfo *utilhint.PlanHints + // InternalHintInfo stores a synthesized LEADING preference used only by the + // order-aware reorder rule. It must not be treated as a user hint. + InternalHintInfo *utilhint.PlanHints + PreferJoinType uint + PreferJoinOrder bool + InternalPreferJoinOrder bool + LeftPreferJoinType uint + RightPreferJoinType uint EqualConditions []*expression.ScalarFunction `hash64-equals:"true" shallow-ref:"true"` // NAEQConditions means null aware equal conditions, which is used for null aware semi joins. @@ -91,11 +95,21 @@ type LogicalJoin struct { FullSchema *expression.Schema FullNames types.NameSlice + // PreferCorrelate is set to true when this SemiJoin originated from a non-correlated + // IN subquery during the correlate alternative round, indicating that the CorrelateSolver + // should convert it back to a correlated Apply with index lookups. + PreferCorrelate bool + // EqualCondOutCnt indicates the estimated count of joined rows after evaluating `EqualConditions`. EqualCondOutCnt float64 // allJoinLeaf is used to identify the table where the column is located during constant propagation. allJoinLeaf []*expression.Schema + + // FromDecorrelatedApply marks joins that come from decorrelating an Apply in the + // first logical round. It is only used to decide whether an equivalent same-order + // PhysicalIndexJoin candidate has already been generated. + FromDecorrelatedApply bool } // Init initializes LogicalJoin. @@ -1979,11 +1993,13 @@ func (p *LogicalJoin) SemiJoinRewrite() (base.LogicalPlan, error) { subAgg.SetSchema(expression.NewSchema(aggOutputCols...)) subAgg.BuildSelfKeyInfo(subAgg.Schema()) innerJoin := LogicalJoin{ - JoinType: base.InnerJoin, - HintInfo: p.HintInfo, - PreferJoinType: p.PreferJoinType, - PreferJoinOrder: p.PreferJoinOrder, - EqualConditions: make([]*expression.ScalarFunction, 0, len(p.EqualConditions)), + JoinType: base.InnerJoin, + HintInfo: p.HintInfo, + InternalHintInfo: p.InternalHintInfo, + PreferJoinType: p.PreferJoinType, + PreferJoinOrder: p.PreferJoinOrder, + InternalPreferJoinOrder: p.InternalPreferJoinOrder, + EqualConditions: make([]*expression.ScalarFunction, 0, len(p.EqualConditions)), }.Init(p.SCtx(), p.QueryBlockOffset()) innerJoin.SetChildren(p.Children()[0], subAgg) innerJoin.SetSchema(expression.MergeSchema(p.Children()[0].Schema().Clone(), subAgg.Schema().Clone())) diff --git a/pkg/planner/core/operator/physicalop/physical_index_join.go b/pkg/planner/core/operator/physicalop/physical_index_join.go index 79e851ee2aef1..b697d513633b1 100644 --- a/pkg/planner/core/operator/physicalop/physical_index_join.go +++ b/pkg/planner/core/operator/physicalop/physical_index_join.go @@ -66,6 +66,10 @@ type PhysicalIndexJoin struct { InnerHashKeys []*expression.Column // EqualConditions stores the equal conditions for logical join's original EqualConditions. EqualConditions []*expression.ScalarFunction `plan-cache-clone:"shallow"` + + // FromDecorrelatedApply is true only when this IndexJoin keeps the original + // Apply outer/inner order after decorrelation. + FromDecorrelatedApply bool } // Init initializes PhysicalIndexJoin. @@ -99,6 +103,7 @@ func (p *PhysicalIndexJoin) Clone(newCtx base.PlanContext) (base.PhysicalPlan, e cloned.CompareFilters = p.CompareFilters.cloneForPlanCache() cloned.OuterHashKeys = util.CloneCols(p.OuterHashKeys) cloned.InnerHashKeys = util.CloneCols(p.InnerHashKeys) + cloned.FromDecorrelatedApply = p.FromDecorrelatedApply return cloned, nil } diff --git a/pkg/planner/core/optimizer.go b/pkg/planner/core/optimizer.go index 43164599199cb..336134a3aab4d 100644 --- a/pkg/planner/core/optimizer.go +++ b/pkg/planner/core/optimizer.go @@ -103,9 +103,11 @@ var optRuleList = []base.LogicalOptRule{ &DeriveTopNFromWindow{}, &rule.PredicateSimplification{}, &PushDownTopNOptimizer{}, + &rule.OrderAwareJoinReorder{}, &rule.SyncWaitStatsLoadPoint{}, &JoinReOrderSolver{}, &rule.OuterJoinToSemiJoin{}, + &CorrelateSolver{}, &rule.ColumnPruner{}, // column pruning again at last, note it will mess up the results of buildKeySolver &PushDownSequenceSolver{}, &EliminateUnionAllDualItem{}, @@ -345,10 +347,6 @@ func VolcanoOptimize(ctx context.Context, sctx base.PlanContext, flag uint64, lo } func adjustOptimizationFlags(flag uint64, logic base.LogicalPlan) uint64 { - // If there is something after flagPrunColumns, do FlagPruneColumnsAgain. - if flag&rule.FlagPruneColumns > 0 && flag-rule.FlagPruneColumns > rule.FlagPruneColumns { - flag |= rule.FlagPruneColumnsAgain - } if checkStableResultMode(logic.SCtx()) { flag |= rule.FlagStabilizeResults } @@ -364,6 +362,16 @@ func adjustOptimizationFlags(flag uint64, logic base.LogicalPlan) uint64 { if !logic.SCtx().GetSessionVars().StmtCtx.UseDynamicPruneMode { flag |= rule.FlagPartitionProcessor // apply partition pruning under static mode } + // FlagCorrelate is added by the correlate alternative round's flag adjuster, + // not here. EnableCorrelateSubquery is an internal flag toggled by the round. + // A second column-prune pass is worthwhile when any rule above column + // pruning is enabled. + if flag&rule.FlagPruneColumns != 0 { + const abovePruneColumns = ^(rule.FlagPruneColumns | (rule.FlagPruneColumns - 1)) + if flag&abovePruneColumns != 0 { + flag |= rule.FlagPruneColumnsAgain + } + } return flag } @@ -986,7 +994,9 @@ func normalizeOptimize(ctx context.Context, flag uint64, logic base.LogicalPlan) func logicalOptimize(ctx context.Context, flag uint64, logic base.LogicalPlan) (base.LogicalPlan, error) { defer func(begin time.Time) { - logic.SCtx().GetSessionVars().DurationOptimizer.LogicalOpt = time.Since(begin) + if logic != nil { + logic.SCtx().GetSessionVars().DurationOptimizer.LogicalOpt = time.Since(begin) + } }(time.Now()) var err error diff --git a/pkg/planner/core/optimizer_test.go b/pkg/planner/core/optimizer_test.go index 90a7837b759dc..9b3634a765144 100644 --- a/pkg/planner/core/optimizer_test.go +++ b/pkg/planner/core/optimizer_test.go @@ -15,6 +15,7 @@ package core import ( + "math/bits" "reflect" "strings" "testing" @@ -27,6 +28,7 @@ import ( "github.com/pingcap/tidb/pkg/parser/mysql" "github.com/pingcap/tidb/pkg/planner/core/base" "github.com/pingcap/tidb/pkg/planner/core/operator/physicalop" + "github.com/pingcap/tidb/pkg/planner/core/rule" "github.com/pingcap/tidb/pkg/planner/property" "github.com/pingcap/tidb/pkg/planner/util/coretestsdk" "github.com/pingcap/tidb/pkg/types" @@ -455,3 +457,18 @@ func TestCanTiFlashUseHashJoinV2(t *testing.T) { // can not use hash join v2 due to null eq require.False(t, hashJoin.CanTiFlashUseHashJoinV2(sctx)) } + +func TestOptRuleListFlagAlignment(t *testing.T) { + // Each position i in optRuleList is gated by the flag bit 1< 0 { + clone.PartitionBy = append([]property.SortItem(nil), lim.PartitionBy...) + } + clone.SetChildren(children...) + return &clone, true +} + +func cloneSort(s *logicalop.LogicalSort) (*logicalop.LogicalSort, bool) { + children, ok := cloneWithChildren(s) + if !ok { + return nil, false + } + clone := *s + clone.BaseLogicalPlan = logicalop.NewBaseLogicalPlan( + s.SCtx(), s.TP(), &clone, s.QueryBlockOffset()) + // LogicalSort embeds BaseLogicalPlan (not LogicalSchemaProducer), + // so it inherits schema from its child — no SetSchema needed. + clone.ByItems = append([]*util.ByItems(nil), s.ByItems...) + clone.SetChildren(children...) + return &clone, true +} + +func cloneTopN(tn *logicalop.LogicalTopN) (*logicalop.LogicalTopN, bool) { + children, ok := cloneWithChildren(tn) + if !ok { + return nil, false + } + clone := *tn + clone.BaseLogicalPlan = logicalop.NewBaseLogicalPlan( + tn.SCtx(), tn.TP(), &clone, tn.QueryBlockOffset()) + clone.SetSchema(tn.Schema().Clone()) + clone.ByItems = append([]*util.ByItems(nil), tn.ByItems...) + if len(tn.PartitionBy) > 0 { + clone.PartitionBy = append([]property.SortItem(nil), tn.PartitionBy...) + } + clone.SetChildren(children...) + return &clone, true +} + +// freshAccessPath creates a new AccessPath with only the structural identity +// fields from the source path (Index, StoreType, handle flags, hint flags). +// Analysis fields (Ranges, AccessConds, IdxCols, etc.) are left at zero so +// that fillIndexPath / deriveTablePathStats start from a clean state. +// +// Index-merge fields (PartialIndexPaths, PartialAlternativeIndexPaths, etc.) +// are intentionally omitted: AllPossibleAccessPaths contains only individual +// index paths; index merge paths are synthesized later by generateIndexMergePath +// which runs as part of DeriveStats after fillIndexPath populates these fresh paths. +func freshAccessPath(src *util.AccessPath) *util.AccessPath { + return &util.AccessPath{ + Index: src.Index, + StoreType: src.StoreType, + IsIntHandlePath: src.IsIntHandlePath, + IsCommonHandlePath: src.IsCommonHandlePath, + Forced: src.Forced, + ForceKeepOrder: src.ForceKeepOrder, + ForceNoKeepOrder: src.ForceNoKeepOrder, + ForcePartialOrder: src.ForcePartialOrder, + IsUkShardIndexPath: src.IsUkShardIndexPath, + IndexLookUpPushDownBy: src.IndexLookUpPushDownBy, + NoncacheableReason: src.NoncacheableReason, + } +} diff --git a/pkg/planner/core/planbuilder.go b/pkg/planner/core/planbuilder.go index 6ffcbdfe25c06..6f475f3064314 100644 --- a/pkg/planner/core/planbuilder.go +++ b/pkg/planner/core/planbuilder.go @@ -250,7 +250,10 @@ type PlanBuilder struct { // finish building the subquery or CTE. handleHelper *handleColHelper + // read-only meta derived from ast node. hintProcessor *hint.QBHintHandler + // mutable state of QBHint when building. + hintState *hint.QBHintBuildState // qbOffset is the offsets of current processing select stmts. qbOffset []int @@ -312,6 +315,50 @@ type PlanBuilder struct { allowBuildCastArray bool // resolveCtx is set when calling Build, it's only effective in the current Build call. resolveCtx *resolve.Context + + // nonViableFTSMatch is set during build when the expression rewriter + // encounters a predicate-context MATCH...AGAINST whose native form + // (FTSMysqlMatchAgainst) cannot be executed — the matched columns lack a + // public FULLTEXT index on a TiFlash-backed table, or the modifier is not + // supported by pushdown. The flag is read by the alternative-rounds driver + // after the round to invalidate the round's plan and trigger the + // fts-like-fallback round (see optimize.go). + nonViableFTSMatch bool + + // predicateMatchSeen is set during build when the expression rewriter + // encounters a direct-boolean-context MATCH...AGAINST (one whose 0/1 boolean + // result is consumed directly as a predicate). The alternative-rounds driver + // uses this to enable the fts-like-fallback round even when round 1's + // native plan is executable, so the LIKE-based plan can compete on cost. + predicateMatchSeen bool +} + +// HasNonViableFTSMatch reports whether the most recent build round saw a +// predicate-context MATCH...AGAINST that could not be served by the native +// FTSMysqlMatchAgainst builtin. The caller (optimize.go) uses this to +// invalidate the round's plan and trigger the fts-like-fallback round. +func (b *PlanBuilder) HasNonViableFTSMatch() bool { + return b.nonViableFTSMatch +} + +// MarkNonViableFTSMatch records that a predicate-context MATCH...AGAINST in +// the current build cannot be served natively. See HasNonViableFTSMatch. +func (b *PlanBuilder) MarkNonViableFTSMatch() { + b.nonViableFTSMatch = true +} + +// HasPredicateMatch reports whether the most recent build round saw a +// direct-boolean-context MATCH...AGAINST. The caller (optimize.go) uses this +// to decide whether to run the fts-like-fallback round for cost competition, +// independent of whether round 1's native plan is executable. +func (b *PlanBuilder) HasPredicateMatch() bool { + return b.predicateMatchSeen +} + +// MarkPredicateMatch records that the current build encountered a +// direct-boolean-context MATCH...AGAINST. See HasPredicateMatch. +func (b *PlanBuilder) MarkPredicateMatch() { + b.predicateMatchSeen = true } type handleColHelper struct { @@ -389,6 +436,11 @@ func GetDBTableInfo(visitInfo []visitInfo) []stmtctx.TableEntry { return tables } +// GetHintState gets the HintState from the PlanBuilder. +func (b *PlanBuilder) GetHintState() *hint.QBHintBuildState { + return b.hintState +} + // GetOptFlag gets the OptFlag of the PlanBuilder. func (b *PlanBuilder) GetOptFlag() uint64 { if b.isSampling { @@ -466,6 +518,9 @@ func (b *PlanBuilder) Init(sctx base.PlanContext, is infoschema.InfoSchema, proc b.ctx = sctx b.is = is b.hintProcessor = processor + if processor != nil { + b.hintState = processor.NewBuildState() + } b.isForUpdateRead = sctx.GetSessionVars().IsPessimisticReadConsistency() b.noDecorrelate = sctx.GetSessionVars().EnableNoDecorrelateInSelect if savedBlockNames == nil { @@ -507,6 +562,14 @@ func (b *PlanBuilder) ResetForReuse() *PlanBuilder { return b } +// HandleUnusedViewHints appends warnings for unused view hints in the current build. +func (b *PlanBuilder) HandleUnusedViewHints() { + if b.hintProcessor == nil { + return + } + b.hintProcessor.SetWarns(b.hintProcessor.HandleUnusedViewHints(b.hintState, nil)) +} + // Build builds the ast node to a Plan. func (b *PlanBuilder) Build(ctx context.Context, node *resolve.NodeW) (base.Plan, error) { err := b.checkSEMStmt(node.Node) diff --git a/pkg/planner/core/rule/BUILD.bazel b/pkg/planner/core/rule/BUILD.bazel index d8b343a092c83..b386d2d24f4ec 100644 --- a/pkg/planner/core/rule/BUILD.bazel +++ b/pkg/planner/core/rule/BUILD.bazel @@ -11,6 +11,7 @@ go_library( "rule_constant_propagation.go", "rule_init.go", "rule_max_min_eliminate.go", + "rule_order_aware_join_reorder.go", "rule_outer_join_to_semi_join.go", "rule_partition_processor.go", "rule_predicate_simplification.go", @@ -28,6 +29,7 @@ go_library( "//pkg/parser/mysql", "//pkg/planner/core/base", "//pkg/planner/core/constraint", + "//pkg/planner/core/joinorder", "//pkg/planner/core/operator/logicalop", "//pkg/planner/core/rule/util", "//pkg/planner/planctx", diff --git a/pkg/planner/core/rule/logical_rules.go b/pkg/planner/core/rule/logical_rules.go index 9852a3867593d..f26435f578ef4 100644 --- a/pkg/planner/core/rule/logical_rules.go +++ b/pkg/planner/core/rule/logical_rules.go @@ -38,9 +38,11 @@ const ( FlagDeriveTopNFromWindow FlagPredicateSimplification FlagPushDownTopN + FlagOrderAwareJoinReorder FlagSyncWaitStatsLoadPoint FlagJoinReOrder FlagOuterJoinToSemiJoin + FlagCorrelate FlagPruneColumnsAgain FlagPushDownSequence FlagEliminateUnionAllDualItem diff --git a/pkg/planner/core/rule/rule_order_aware_join_reorder.go b/pkg/planner/core/rule/rule_order_aware_join_reorder.go new file mode 100644 index 0000000000000..478aacfb6a03d --- /dev/null +++ b/pkg/planner/core/rule/rule_order_aware_join_reorder.go @@ -0,0 +1,245 @@ +// Copyright 2026 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package rule + +import ( + "context" + "slices" + + "github.com/pingcap/tidb/pkg/expression" + "github.com/pingcap/tidb/pkg/planner/core/base" + "github.com/pingcap/tidb/pkg/planner/core/joinorder" + "github.com/pingcap/tidb/pkg/planner/core/operator/logicalop" + plannerutil "github.com/pingcap/tidb/pkg/planner/util" +) + +// OrderAwareJoinReorder annotates a join group with an internal leading +// preference when a TopN above the group can benefit from keeping one leaf's +// index order alive. +type OrderAwareJoinReorder struct{} + +// Optimize implements the base.LogicalOptRule.<0th> interface. +func (r *OrderAwareJoinReorder) Optimize(_ context.Context, p base.LogicalPlan) (base.LogicalPlan, bool, error) { + changed, _, err := r.optimizeRecursive(p, nil, nil) + return p, changed, err +} + +func (r *OrderAwareJoinReorder) optimizeRecursive( + p base.LogicalPlan, + orderCols []*expression.Column, + midFilters []expression.Expression, +) (changed bool, ordered bool, err error) { + if p == nil { + return false, false, nil + } + if _, ok := p.(*logicalop.LogicalCTE); ok { + return false, false, nil + } + if len(orderCols) == 0 { + // only selection filter under order requirement can be used. + midFilters = nil + } + + switch node := p.(type) { + // for TopN and Sort, we extract the ordering columns and pass down to children so they can annotate join groups with leading preferences! + case *logicalop.LogicalTopN: + extractedOrder := extractOrderingColumns(node.ByItems) + childChanged, childOrdered, err := r.optimizeChildren(node.Children(), extractedOrder, nil, 0) + if err != nil { + return false, false, err + } + if len(orderCols) > 0 { + return changed || childChanged, sameOrderingColumns(orderCols, extractedOrder), nil + } + return changed || childChanged, childOrdered, nil + case *logicalop.LogicalSort: + extractedOrder := extractOrderingColumns(node.ByItems) + childChanged, childOrdered, err := r.optimizeChildren(node.Children(), extractedOrder, nil, 0) + if err != nil { + return false, false, err + } + if len(orderCols) > 0 { + return changed || childChanged, sameOrderingColumns(orderCols, extractedOrder), nil + } + return changed || childChanged, childOrdered, nil + case *logicalop.LogicalProjection: + rewrittenOrder := rewriteOrderingForProjection(node, orderCols) + childChanged, childOrdered, err := r.optimizeChildren(node.Children(), rewrittenOrder, midFilters, 0) + if err != nil { + return false, false, err + } + if len(orderCols) > 0 { + return changed || childChanged, len(rewrittenOrder) > 0 && childOrdered, nil + } + return changed || childChanged, childOrdered, nil + case *logicalop.LogicalLimit: + childChanged, childOrdered, err := r.optimizeChildren(node.Children(), orderCols, midFilters, 0) + return changed || childChanged, childOrdered, err + case *logicalop.LogicalSelection: + canPushThroughSelection := node.SCtx().GetSessionVars().TiDBOptJoinReorderThroughSel && + !slices.ContainsFunc(node.Conditions, expression.IsMutableEffectsExpr) + if canPushThroughSelection { + var accumulatedFilters []expression.Expression + if len(orderCols) > 0 { + // These filters may help child groups preserve the same ordering + // by fixing leading index columns above the current anchor join. + accumulatedFilters = append(slices.Clone(midFilters), node.Conditions...) + } + var localChoice *joinorder.OrderedLeadingChoice + if len(orderCols) > 0 && shouldUseCDCBasedJoinReorder(node) { + localChoice = joinorder.FindOrderedLeadingChoice(node, orderCols) + } + if localChoice != nil && len(localChoice.Vertices) > 0 { + // This subtree owns the required ordering columns, so recurse into it + // first and only annotate the current anchor after the chosen child + // proves it can still satisfy the order requirement. + childChanged, childOrdered, err := r.optimizeChildren(localChoice.Vertices, orderCols, accumulatedFilters, localChoice.CarrierVertex.ID()) + if err != nil { + return false, false, err + } + if childOrdered && joinorder.TryAnnotateOrderedLeading(node, localChoice) { + changed = true + return changed || childChanged, true, nil + } + return changed || childChanged, false, nil + } + childChanged, childOrdered, err := r.optimizeChildren(node.Children(), orderCols, accumulatedFilters, 0) + return changed || childChanged, childOrdered, err + } + childChanged, _, err := r.optimizeChildren(node.Children(), nil, nil, 0) + return changed || childChanged, false, err + case *logicalop.LogicalJoin: + var localChoice *joinorder.OrderedLeadingChoice + if len(orderCols) > 0 && shouldUseCDCBasedJoinReorder(node) { + localChoice = joinorder.FindOrderedLeadingChoice(node, orderCols) + } + if localChoice != nil && len(localChoice.Vertices) > 0 { + childChanged, childOrdered, err := r.optimizeChildren(localChoice.Vertices, orderCols, midFilters, localChoice.CarrierVertex.ID()) + if err != nil { + return false, false, err + } + if childOrdered && joinorder.TryAnnotateOrderedLeading(node, localChoice) { + changed = true + return changed || childChanged, true, nil + } + return changed || childChanged, false, nil + } + // The order requirement does not belong to any vertex of this join group, + // so there is no subtree worth propagating into from this point. + childChanged, _, err := r.optimizeChildren(node.Children(), nil, nil, 0) + return changed || childChanged, false, err + case *logicalop.DataSource: + if len(orderCols) == 0 { + return false, false, nil + } + return false, joinorder.DsSatisfiesOrdering(node, orderCols, midFilters), nil + default: + childChanged, _, err := r.optimizeChildren(p.Children(), nil, nil, 0) + return changed || childChanged, false, err + } +} + +func (r *OrderAwareJoinReorder) optimizeChildren( + children []base.LogicalPlan, + orderCols []*expression.Column, + parentFilters []expression.Expression, + vertexIDShouldFollowOrder int, +) (changed bool, ordered bool, err error) { + for _, child := range children { + nextOrderCols := orderCols + nextParentFilters := parentFilters + if vertexIDShouldFollowOrder == 0 || vertexIDShouldFollowOrder == child.ID() { + // A zero vertex ID means we are still walking the tree to find the + // first anchor join, so every child keeps the current requirement. + // Once a join group chooses one carrier vertex, only that vertex + // continues to inherit the ordering and accumulated filters. + childChanged, childOrdered, err := r.optimizeRecursive(child, nextOrderCols, nextParentFilters) + if err != nil { + return false, false, err + } + changed = changed || childChanged + ordered = ordered || childOrdered + continue + } + childChanged, _, err := r.optimizeRecursive(child, nil, nil) + if err != nil { + return false, false, err + } + changed = changed || childChanged + } + return changed, ordered, nil +} + +func shouldUseCDCBasedJoinReorder(p base.LogicalPlan) bool { + vars := p.SCtx().GetSessionVars() + return vars.TiDBOptEnableAdvancedJoinReorder && vars.TiDBOptJoinReorderThreshold <= 0 +} + +func extractOrderingColumns(items []*plannerutil.ByItems) []*expression.Column { + if len(items) == 0 { + return nil + } + cols := make([]*expression.Column, 0, len(items)) + for _, item := range items { + // The current matcher only reasons about forward index order, so bail out + // once ORDER BY contains a descending item instead of silently treating it + // as ascending. + if item.Desc { + return nil + } + col, ok := item.Expr.(*expression.Column) + if !ok { + return nil + } + cols = append(cols, col) + } + return cols +} + +func sameOrderingColumns(left, right []*expression.Column) bool { + if len(left) == 0 || len(right) == 0 { + return false + } + return slices.EqualFunc(left, right, func(leftCol, rightCol *expression.Column) bool { + return leftCol != nil && rightCol != nil && leftCol.UniqueID == rightCol.UniqueID + }) +} + +func rewriteOrderingForProjection( + proj *logicalop.LogicalProjection, + orderCols []*expression.Column, +) []*expression.Column { + if proj == nil || len(orderCols) == 0 { + return nil + } + rewritten := make([]*expression.Column, 0, len(orderCols)) + for _, col := range orderCols { + offset := proj.Schema().ColumnIndex(col) + if offset < 0 { + return nil + } + mappedCol, ok := proj.Exprs[offset].(*expression.Column) + if !ok { + return nil + } + rewritten = append(rewritten, mappedCol) + } + return rewritten +} + +// Name implements the base.LogicalOptRule.<1st> interface. +func (*OrderAwareJoinReorder) Name() string { + return "order_aware_join_reorder" +} diff --git a/pkg/planner/core/rule_correlate.go b/pkg/planner/core/rule_correlate.go new file mode 100644 index 0000000000000..ac7d6e99785ad --- /dev/null +++ b/pkg/planner/core/rule_correlate.go @@ -0,0 +1,345 @@ +// Copyright 2026 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package core + +import ( + "context" + "fmt" + + "github.com/pingcap/tidb/pkg/expression" + "github.com/pingcap/tidb/pkg/parser/mysql" + "github.com/pingcap/tidb/pkg/planner/core/base" + "github.com/pingcap/tidb/pkg/planner/core/operator/logicalop" + "github.com/pingcap/tidb/pkg/planner/util" + "github.com/pingcap/tidb/pkg/types" + "github.com/pingcap/tidb/pkg/util/logutil" + "go.uber.org/zap" +) + +// CorrelateSolver tries to convert semi-join LogicalJoin back to correlated LogicalApply. +// This is the reverse of DecorrelateSolver and is useful when a correlated nested-loop +// (index lookup per outer row) might be more efficient than a hash semi-join. +type CorrelateSolver struct{} + +// Optimize implements base.LogicalOptRule.<0th> interface. +func (s *CorrelateSolver) Optimize(ctx context.Context, p base.LogicalPlan) (retPlan base.LogicalPlan, retChanged bool, retErr error) { + defer func() { + if r := recover(); r != nil { + logutil.BgLogger().Warn("CorrelateSolver panic", + zap.Any("recover", r), + zap.Stack("stack")) + retPlan = nil + retChanged = false + retErr = fmt.Errorf("CorrelateSolver panic: %v", r) + } + }() + return s.correlate(ctx, p) +} + +func (s *CorrelateSolver) correlate(ctx context.Context, p base.LogicalPlan) (base.LogicalPlan, bool, error) { + // CTE's logical optimization is independent. + if _, ok := p.(*logicalop.LogicalCTE); ok { + return p, false, nil + } + + // First recurse into children. + planChanged := false + newChildren := make([]base.LogicalPlan, 0, len(p.Children())) + for _, child := range p.Children() { + np, changed, err := s.correlate(ctx, child) + if err != nil { + return nil, false, err + } + planChanged = planChanged || changed + newChildren = append(newChildren, np) + } + p.SetChildren(newChildren...) + + // Check if this node is a LogicalApply — if so, skip (already correlated). + if _, isApply := p.(*logicalop.LogicalApply); isApply { + return p, planChanged, nil + } + + // Check if this node is a LogicalJoin with a semi-join type that was + // marked for re-correlation (from a non-correlated IN subquery). + join, isJoin := p.(*logicalop.LogicalJoin) + if !isJoin || !join.JoinType.IsSemiJoin() || !join.PreferCorrelate { + return p, planChanged, nil + } + + // Must have EqualConditions to correlate (skip if only NAEQConditions). + if len(join.EqualConditions) == 0 { + return p, planChanged, nil + } + + // For v1: skip null-aware conditions, LeftConditions, and OtherConditions. + if len(join.NAEQConditions) > 0 || len(join.LeftConditions) > 0 || len(join.OtherConditions) > 0 { + return p, planChanged, nil + } + + leftSchema := join.Children()[0].Schema() + rightSchema := join.Children()[1].Schema() + + // Left outer semi joins (scalar IN / NOT IN) require 3-valued NULL + // semantics: the joiner must distinguish "no match" (→ 0) from "unknown + // due to NULL" (→ NULL). It does this by evaluating the equality join + // condition and tracking whether any comparison returned NULL. + // + // When we push the equality into the inner side as a correlated filter + // (rightCol = CorCol(leftCol)), two problems arise: + // 1. If the inner column is nullable, NULL inner values are silently + // filtered out (NULL = X → NULL → filtered), so the joiner never + // sees them and returns 0 instead of NULL. + // 2. If the outer column is nullable and its value is NULL, the + // correlated filter becomes rightCol = NULL, which filters out all + // inner rows, and the joiner returns 0 instead of NULL. + // + // Skip unless ALL equality columns on both sides are proven NOT NULL. + if join.JoinType == base.LeftOuterSemiJoin || join.JoinType == base.AntiLeftOuterSemiJoin { + for _, eqCond := range join.EqualConditions { + col0, col1, ok := expression.IsColOpCol(eqCond) + if !ok { + return p, planChanged, nil + } + leftCol := leftSchema.RetrieveColumn(col0) + rightCol := rightSchema.RetrieveColumn(col1) + if leftCol == nil || rightCol == nil { + leftCol = leftSchema.RetrieveColumn(col1) + rightCol = rightSchema.RetrieveColumn(col0) + } + if leftCol == nil || rightCol == nil { + return p, planChanged, nil + } + if !mysql.HasNotNullFlag(leftCol.RetType.GetFlag()) || !mysql.HasNotNullFlag(rightCol.RetType.GetFlag()) { + return p, planChanged, nil + } + } + } + + selConds := make([]expression.Expression, 0, len(join.EqualConditions)+len(join.RightConditions)) + corCols := make([]*expression.CorrelatedColumn, 0, len(join.EqualConditions)) + + // Convert EqualConditions to correlated conditions. + for _, eqCond := range join.EqualConditions { + cond, corCol := s.buildCorrelatedCond(eqCond, leftSchema, rightSchema, join) + if cond == nil { + // Can't correlate this condition; abort. + return p, planChanged, nil + } + selConds = append(selConds, cond) + corCols = append(corCols, corCol) + } + + // Move RightConditions to the selection (they reference only the inner side). + selConds = append(selConds, join.RightConditions...) + + // Clone the inner subtree so PPD can modify the clone without affecting + // the Join's inner child (which must retain its original conditions). + // If the subtree contains an unhandled operator type, abort to avoid corruption. + clonedInner, ok := cloneLogicalSubtree(join.Children()[1]) + if !ok { + return p, planChanged, nil + } + + // Lift DataSource conditions back into Selection nodes. The original PPD + // pushed conditions all the way into DataSource.AllConds and cleared them + // from ancestor operators (e.g., Join.RightConditions). When we re-run PPD + // below, the Join re-collects conditions from its own fields (not from + // DataSource.AllConds), so conditions that were pushed past the Join would + // be lost. Wrapping each DataSource in a Selection restores the pre-PPD + // state so the re-run can properly redistribute all conditions. + clonedInner = liftDataSourceConds(clonedInner) + + sel := logicalop.LogicalSelection{Conditions: selConds}.Init(join.SCtx(), join.QueryBlockOffset()) + sel.SetChildren(clonedInner) + + // Run predicate push-down on the inner subtree so the new correlated + // predicates reach the DataSource (for index access path selection). + // PPD has already finished by the time this rule runs, so without this + // local pass the predicates would stay in the Selection and the inner + // side could only do full scans. + _, innerPlan, err := sel.PredicatePushDown(nil) + if err != nil { + // PPD failed (e.g., conditions reference columns pruned from the + // DataSource schema); abort the correlate optimization. + return p, planChanged, nil + } + + // Reset stats on DataSources that received correlated conditions so DeriveStats + // re-runs during physical optimization. This is necessary because the original + // DeriveStats ran before the correlate rule added correlated conditions, so the + // index access paths were built without them. + resetStatsForCorrelatedDS(innerPlan) + + // For semi-join semantics (EXISTS/IN and NOT EXISTS/NOT IN), add Limit 1 on + // the inner side. The Apply executor materializes all inner rows per outer + // key via fetchAllInners; a Limit 1 enables early exit since semi/anti-semi + // joins only need to know whether any matching row exists. + // This mirrors what expression_rewriter does for NO_DECORRELATE EXISTS. + if !hasLimit(innerPlan) { + limit := logicalop.LogicalLimit{Count: 1}.Init(join.SCtx(), join.QueryBlockOffset()) + limit.SetChildren(innerPlan) + innerPlan = limit + } + + // Build the LogicalApply. + ap := logicalop.LogicalApply{}.Init(join.SCtx(), join.QueryBlockOffset()) + ap.JoinType = join.JoinType + ap.CorCols = corCols + // Copy hint fields so hint behavior is preserved in the alternative. + ap.HintInfo = join.HintInfo + ap.PreferJoinType = join.PreferJoinType + ap.PreferJoinOrder = join.PreferJoinOrder + ap.LeftPreferJoinType = join.LeftPreferJoinType + ap.RightPreferJoinType = join.RightPreferJoinType + ap.SetChildren(join.Children()[0], innerPlan) + ap.SetSchema(join.Schema().Clone()) + ap.SetOutputNames(join.OutputNames()) + + // Replace the Join with the Apply. In the alternative logical plans framework, + // this round produces a complete plan; the top-level cost comparison across + // rounds selects the winner. + return ap, true, nil +} + +// buildCorrelatedCond converts an equal condition from the join into a correlated condition +// for the inner selection. It identifies which column comes from the left (outer) side and +// creates a CorrelatedColumn for it, then builds a new condition: rightCol CorCol(leftCol). +func (*CorrelateSolver) buildCorrelatedCond( + eqCond *expression.ScalarFunction, + leftSchema *expression.Schema, + rightSchema *expression.Schema, + join *logicalop.LogicalJoin, +) (expression.Expression, *expression.CorrelatedColumn) { + col0, col1, ok := expression.IsColOpCol(eqCond) + if !ok { + return nil, nil + } + + // Determine which column is from the left (outer) side and which from the right (inner). + leftCol := leftSchema.RetrieveColumn(col0) + rightCol := rightSchema.RetrieveColumn(col1) + if leftCol == nil || rightCol == nil { + // Try swapped order. + leftCol = leftSchema.RetrieveColumn(col1) + rightCol = rightSchema.RetrieveColumn(col0) + } + if leftCol == nil || rightCol == nil { + return nil, nil + } + + // Create a CorrelatedColumn for the outer (left) column. + // Data must be initialized (non-nil) to avoid panics during physical planning. + corCol := &expression.CorrelatedColumn{Column: *leftCol, Data: new(types.Datum)} + + // Create the correlated condition: rightCol CorCol(leftCol). + cond := expression.NewFunctionInternal( + join.SCtx().GetExprCtx(), + eqCond.FuncName.L, + types.NewFieldType(mysql.TypeTiny), + rightCol, corCol, + ) + + return cond, corCol +} + +// liftDataSourceConds walks the plan tree and for each DataSource with +// non-empty AllConds, wraps it in a Selection node containing those conditions. +// This "un-pushes" conditions that the original PPD pushed into DataSources, +// so that a subsequent PPD re-run (in correlate()) can properly redistribute +// all conditions — including those that would otherwise be silently dropped +// when DataSource.PredicatePushDown overwrites AllConds. +func liftDataSourceConds(p base.LogicalPlan) base.LogicalPlan { + // Recurse into children first, potentially replacing them. + for i, child := range p.Children() { + newChild := liftDataSourceConds(child) + if newChild != child { + p.Children()[i] = newChild + } + } + + // If this is a DataSource with AllConds, wrap it in a Selection. + if ds, ok := p.(*logicalop.DataSource); ok && len(ds.AllConds) > 0 { + sel := logicalop.LogicalSelection{ + Conditions: ds.AllConds, + }.Init(ds.SCtx(), ds.QueryBlockOffset()) + sel.SetChildren(ds) + + // Clear DataSource conditions; the PPD re-run will push them back. + ds.AllConds = nil + ds.PushedDownConds = nil + + return sel + } + + return p +} + +// resetStatsForCorrelatedDS walks the inner subtree and clears StatsInfo on +// DataSources that have correlated conditions in AllConds, plus all ancestor +// plan nodes up to the root. This forces DeriveStats to re-run during physical +// optimization so that index access paths are rebuilt with the correlated +// conditions. +// +// For correlated DataSources, fresh AccessPaths are created so fillIndexPath +// starts from a clean state with the new correlated conditions. Non-correlated +// DataSources retain their deep-cloned AccessPaths and stats (set during +// cloning) so DeriveStats returns early — this avoids failures when conditions +// reference columns that column pruning removed from the DataSource's schema. +func resetStatsForCorrelatedDS(p base.LogicalPlan) bool { + hasCorrelated := false + + // Check if this is a DataSource with correlated conditions. + if ds, ok := p.(*logicalop.DataSource); ok { + for _, cond := range ds.AllConds { + if len(expression.ExtractCorColumns(cond)) > 0 { + hasCorrelated = true + break + } + } + if hasCorrelated { + // Create fresh AccessPaths so fillIndexPath rebuilds them with the + // correlated conditions from a clean state. + origPaths := ds.AllPossibleAccessPaths + ds.AllPossibleAccessPaths = make([]*util.AccessPath, len(origPaths)) + for i, ap := range origPaths { + ds.AllPossibleAccessPaths[i] = freshAccessPath(ap) + } + ds.PossibleAccessPaths = append([]*util.AccessPath(nil), ds.AllPossibleAccessPaths...) + } + } + + // Recurse into children. + for _, child := range p.Children() { + if resetStatsForCorrelatedDS(child) { + hasCorrelated = true + } + } + + // Reset stats on this node if it or any descendant has correlated conditions. + // This ensures DeriveStats re-runs for the affected subtree path. + if hasCorrelated { + if blp, ok := p.GetBaseLogicalPlan().(*logicalop.BaseLogicalPlan); ok { + blp.SetStats(nil) + } + } + + return hasCorrelated +} + +// Name implements base.LogicalOptRule.<1st> interface. +func (*CorrelateSolver) Name() string { + return "correlate" +} diff --git a/pkg/planner/core/rule_decorrelate.go b/pkg/planner/core/rule_decorrelate.go index 75db59192e68a..7460bdbbb4529 100644 --- a/pkg/planner/core/rule_decorrelate.go +++ b/pkg/planner/core/rule_decorrelate.go @@ -231,6 +231,10 @@ func (s *DecorrelateSolver) optimize(ctx context.Context, p base.LogicalPlan, gr join := &apply.LogicalJoin join.SetSelf(join) join.SetTP(plancodec.TypeJoin) + if p.SCtx().GetSessionVars().EnableAlternativeLogicalPlans { + p.SCtx().GetSessionVars().StmtCtx.MarkAlternativeLogicalPlanDecorrelatedApply() + join.FromDecorrelatedApply = true + } p = join } else if apply.NoDecorrelate { goto NoOptimize diff --git a/pkg/planner/core/rule_join_reorder.go b/pkg/planner/core/rule_join_reorder.go index 881b041f09c8b..ed7156666ce53 100644 --- a/pkg/planner/core/rule_join_reorder.go +++ b/pkg/planner/core/rule_join_reorder.go @@ -67,6 +67,9 @@ func extractJoinGroup(p base.LogicalPlan) *joinGroupResult { // We need to return the hint information to warn joinOrderHintInfo = append(joinOrderHintInfo, join.HintInfo) currentLeadingHint = join.HintInfo + } else if isJoin && join.InternalPreferJoinOrder { + joinOrderHintInfo = append(joinOrderHintInfo, join.InternalHintInfo) + currentLeadingHint = join.InternalHintInfo } // If the variable `tidb_opt_advanced_join_hint` is false and the join node has the join method hint, we will not split the current join node to join reorder process. @@ -81,6 +84,7 @@ func extractJoinGroup(p base.LogicalPlan) *joinGroupResult { if joinOrderHintInfo != nil { // The leading hint can not work for some reasons. So clear it in the join node. join.HintInfo = nil + join.InternalHintInfo = nil } return &joinGroupResult{ group: []base.LogicalPlan{p}, @@ -256,6 +260,10 @@ type joinTypeWithExtMsg struct { // Optimize implements the base.LogicalOptRule.<0th> interface. func (s *JoinReOrderSolver) Optimize(_ context.Context, p base.LogicalPlan) (base.LogicalPlan, bool, error) { + if p.SCtx().GetSessionVars().TiDBOptEnableAdvancedJoinReorder { + p, err := joinorder.Optimize(p) + return p, false, err + } p, err := s.optimizeRecursive(p.SCtx(), p) return p, false, err } diff --git a/pkg/planner/core/task.go b/pkg/planner/core/task.go index 45a89e61b9925..be05002160bf2 100644 --- a/pkg/planner/core/task.go +++ b/pkg/planner/core/task.go @@ -203,6 +203,9 @@ func indexJoinAttach2TaskV2(p *physicalop.PhysicalIndexJoin, tasks ...base.Task) outerTask := tasks[1-p.InnerChildIdx].ConvertToRootTask(p.SCtx()) innerTask := tasks[p.InnerChildIdx].ConvertToRootTask(p.SCtx()) completePhysicalIndexJoin(p, innerTask.(*physicalop.RootTask), innerTask.Plan().Schema(), outerTask.Plan().Schema(), true) + if p.FromDecorrelatedApply { + p.SCtx().GetSessionVars().StmtCtx.MarkAlternativeLogicalPlanSameOrderIndexJoin() + } if p.InnerChildIdx == 1 { p.SetChildren(outerTask.Plan(), innerTask.Plan()) } else { diff --git a/pkg/planner/optimize.go b/pkg/planner/optimize.go index 405efe1b525e2..f6967d9b5cbaa 100644 --- a/pkg/planner/optimize.go +++ b/pkg/planner/optimize.go @@ -16,6 +16,7 @@ package planner import ( "context" + stderrors "errors" "math" "math/rand" "sort" @@ -33,6 +34,7 @@ import ( "github.com/pingcap/tidb/pkg/planner/core" "github.com/pingcap/tidb/pkg/planner/core/base" "github.com/pingcap/tidb/pkg/planner/core/resolve" + "github.com/pingcap/tidb/pkg/planner/core/rule" "github.com/pingcap/tidb/pkg/planner/indexadvisor" "github.com/pingcap/tidb/pkg/planner/planctx" "github.com/pingcap/tidb/pkg/planner/property" @@ -47,8 +49,10 @@ import ( "github.com/pingcap/tidb/pkg/util/dbterror/plannererrors" "github.com/pingcap/tidb/pkg/util/hint" "github.com/pingcap/tidb/pkg/util/intest" + "github.com/pingcap/tidb/pkg/util/logutil" "github.com/pingcap/tidb/pkg/util/topsql" "github.com/pingcap/tidb/pkg/util/tracing" + "go.uber.org/zap" ) // getPlanFromNonPreparedPlanCache tries to get an available cached plan from the NonPrepared Plan Cache for this stmt. @@ -438,9 +442,261 @@ var planBuilderPool = sync.Pool{ }, } +type logicalPlanBuildCtx struct { + stmtCtxState stmtctx.LogicalPlanBuildState + plannerSelectBlockAsName *[]ast.HintTable + mapScalarSubQ []any + mapHashCode2UniqueID map[string]int + rewritePhaseInfo variable.RewritePhaseInfo +} + +func saveLogicalPlanBuildCtx(sessVars *variable.SessionVars) logicalPlanBuildCtx { + return logicalPlanBuildCtx{ + stmtCtxState: sessVars.StmtCtx.SaveLogicalPlanBuildState(), + plannerSelectBlockAsName: sessVars.PlannerSelectBlockAsName.Load(), + mapScalarSubQ: sessVars.MapScalarSubQ, + mapHashCode2UniqueID: sessVars.MapHashCode2UniqueID4ExtendedCol, + rewritePhaseInfo: sessVars.RewritePhaseInfo, + } +} + +func restoreLogicalPlanBuildCtx(sessVars *variable.SessionVars, logicalPlanCtx logicalPlanBuildCtx) { + sessVars.StmtCtx.RestoreLogicalPlanBuildState(logicalPlanCtx.stmtCtxState) + sessVars.PlannerSelectBlockAsName.Store(logicalPlanCtx.plannerSelectBlockAsName) + sessVars.MapScalarSubQ = logicalPlanCtx.mapScalarSubQ + sessVars.MapHashCode2UniqueID4ExtendedCol = logicalPlanCtx.mapHashCode2UniqueID + sessVars.RewritePhaseInfo = logicalPlanCtx.rewritePhaseInfo +} + +// maybeArmFTSLikeFallback inspects a native-FTS planning error and decides +// whether this round should be discarded in favor of the MATCH...AGAINST to +// LIKE fallback round. +// +// It only swallows errors that were explicitly marked as fallbackable by the +// native FTS path. If no fallback round is available for the current query +// shape, it unwraps the original error so callers preserve the native message. +func maybeArmFTSLikeFallback( + sessVars *variable.SessionVars, + builder *core.PlanBuilder, + err error, +) (discardRound bool, retErr error) { + if err == nil { + return false, nil + } + + var fallbackErr *base.FTSLikeFallbackError + if !stderrors.As(err, &fallbackErr) { + return false, err + } + err = err.(*base.FTSLikeFallbackError).Unwrap() + if fallbackErr.Cause == nil { + return false, err + } + + // The fallback round only rewrites direct-boolean MATCH predicates. If we + // are already inside that round, or alternative logical plans are disabled, + // or the build never saw a fallback-eligible predicate MATCH, surface the + // original native error unchanged. + if !sessVars.EnableAlternativeLogicalPlans || + sessVars.StmtCtx.AlternativeLogicalPlanFTSLikeFallback || + !builder.HasPredicateMatch() { + return false, fallbackErr.Cause + } + + sessVars.StmtCtx.AlternativeLogicalPlanHasPredicateContextMatch = true + sessVars.StmtCtx.AlternativeLogicalPlanFTSLikeFallback = true + return true, nil +} + +func buildAndOptimizeLogicalPlanRound( + ctx context.Context, + sctx planctx.PlanContext, + node *resolve.NodeW, + is infoschema.InfoSchema, + hintProcessor *hint.QBHintHandler, + checked *bool, + optimizeStarted *bool, + beginOpt *time.Time, + needRestoreLogicalPlanCtx bool, + bestPlan *base.PhysicalPlan, + bestNames *types.NameSlice, + bestCost *float64, + bestLogicalPlanCtx *logicalPlanBuildCtx, + optFlagAdjust func(uint64) uint64, +) (base.Plan, types.NameSlice, bool, error) { + builder := planBuilderPool.Get().(*core.PlanBuilder) + defer planBuilderPool.Put(builder.ResetForReuse()) + // TODO: when buildRound > 1, only emit unused view-hint warnings for the winner build. + defer builder.HandleUnusedViewHints() + + builder.Init(sctx, is, hintProcessor) + + // todo: you can customize each round's special builder (like semi join rewrite or not by signal) + p, err := buildLogicalPlan(ctx, sctx, node, builder) + if err != nil { + return nil, nil, false, err + } + names := p.OutputNames() + + if !*checked { + // Keep privilege and lock checks fail-fast. These depend on visitInfo + // produced by the logical build, but not on the later cost winner. + if pm := privilege.GetPrivilegeManager(sctx); pm != nil { + visitInfo := core.VisitInfo4PrivCheck(ctx, is, node.Node, builder.GetVisitInfo()) + if err := core.CheckPrivilege(sctx.GetSessionVars().ActiveRoles, pm, visitInfo); err != nil { + return nil, nil, false, err + } + } + + if err := core.CheckTableLock(sctx, is, builder.GetVisitInfo()); err != nil { + return nil, nil, false, err + } + + if err := core.CheckTableMode(node); err != nil { + return nil, nil, false, err + } + *checked = true + } + + // Handle the non-logical plan statement. + logic, isLogicalPlan := p.(base.LogicalPlan) + if !isLogicalPlan { + return p, names, true, nil + } + + core.RecheckCTE(logic) + + // todo: also you can customize each round's special logical opt flag here (like decorrelate rule or not) + if !*optimizeStarted { + *optimizeStarted = true + *beginOpt = time.Now() + } + optFlag := builder.GetOptFlag() + if sctx.GetSessionVars().EnableAlternativeLogicalPlans && + optFlag&rule.FlagPushDownTopN > 0 && + optFlag&rule.FlagJoinReOrder > 0 { + sctx.GetSessionVars().StmtCtx.MarkAlternativeLogicalPlanOrderAwareJoinReorder() + } + if optFlagAdjust != nil { + optFlag = optFlagAdjust(optFlag) + } + // when we are sure about we can have a ILIKE fallback for FTS function, we can + // directly ignore the error from AnalyzeTICIIndex phase. + finalPlan, cost, err := core.DoOptimize(ctx, sctx, optFlag, logic) + if err != nil { + if discard, fallbackErr := maybeArmFTSLikeFallback(sctx.GetSessionVars(), builder, err); discard { + return nil, nil, false, nil + } else if fallbackErr != nil { + return nil, nil, false, fallbackErr + } + } + + // Record predicate-context MATCH for cost competition. The fts-like-fallback + // alternative round reads this signal to decide whether to build a competing + // ILIKE-based plan alongside round 1's native plan, so the cheaper of the + // two wins via the normal alt-rounds cost comparison. + if builder.HasPredicateMatch() { + sctx.GetSessionVars().StmtCtx.AlternativeLogicalPlanHasPredicateContextMatch = true + } + // If this round saw a predicate-context MATCH that cannot be served by the + // native FTSMysqlMatchAgainst builtin, the produced plan would fail at + // execution. Discard it and arm AlternativeLogicalPlanFTSLikeFallback so + // any intervening rounds (correlate, etc.) re-rewrite with ILIKE too. The + // fts-like-fallback round below also forces this flag during setup; this + // outer assignment covers the non-viable case where the flag must stay + // true across all subsequent rounds, not just inside the LIKE round. + if builder.HasNonViableFTSMatch() { + sctx.GetSessionVars().StmtCtx.AlternativeLogicalPlanFTSLikeFallback = true + return p, names, false, nil + } + + if *bestPlan == nil || cost < *bestCost { + *bestCost = cost + *bestPlan = finalPlan + *bestNames = names + if needRestoreLogicalPlanCtx { + *bestLogicalPlanCtx = saveLogicalPlanBuildCtx(sctx.GetSessionVars()) + } + } + return p, names, false, nil +} + // optimizeCnt is a global variable only used for test. var optimizeCnt int +func shouldTryNonDecorrelationRound(sessVars *variable.SessionVars) bool { + return sessVars.EnableAlternativeLogicalPlans && + sessVars.StmtCtx.AlternativeLogicalPlanDecorrelatedApply && + !sessVars.StmtCtx.AlternativeLogicalPlanSameOrderIndexJoin +} + +func shouldTryOrderAwareReorderRound(sessVars *variable.SessionVars) bool { + return sessVars.EnableAlternativeLogicalPlans && + sessVars.StmtCtx.AlternativeLogicalPlanOrderAwareJoinReorder +} + +func shouldTryCorrelateRound(sessVars *variable.SessionVars) bool { + return sessVars.EnableAlternativeLogicalPlans && + sessVars.StmtCtx.AlternativeLogicalPlanPreferCorrelate +} + +// alternativeRound describes one alternative logical-plan round. +// adjustFlag adjusts the optimization flags for the round. +// enabled returns true when the round should be attempted. +// setup/cleanup optionally modify session state before/after plan building. +type alternativeRound struct { + name string + adjustFlag func(uint64) uint64 + enabled func(*variable.SessionVars) bool + setup func(*variable.SessionVars) + cleanup func(*variable.SessionVars) +} + +var alternativeRounds = [...]alternativeRound{ + { + name: "non-decorrelate", + adjustFlag: func(flag uint64) uint64 { return flag &^ rule.FlagDecorrelate }, + enabled: shouldTryNonDecorrelationRound, + }, + { + name: "order-aware-reorder", + adjustFlag: func(flag uint64) uint64 { return flag | rule.FlagOrderAwareJoinReorder }, + enabled: shouldTryOrderAwareReorderRound, + }, + { + name: "correlate", + adjustFlag: func(flag uint64) uint64 { return flag | rule.FlagCorrelate }, + enabled: shouldTryCorrelateRound, + setup: func(sv *variable.SessionVars) { + sv.EnableCorrelateSubquery = true + }, + }, + { + // fts-like-fallback: rebuild the plan rewriting predicate-context + // MATCH...AGAINST to ILIKE so it can compete with round 1's native plan + // on cost (and serve as the only valid plan when native is non-viable). + // Round 1 always uses the native builtin (same as Alt-disabled). This + // round fires whenever round 1 saw a direct-boolean-context MATCH + // (HasPredicateContextMatch) — both plans then compete via the strict-`<` + // cost comparison in buildAndOptimizeLogicalPlanRound — or whenever + // round 1 saw a MATCH whose native form cannot execute + // (FTSLikeFallback, set by the round driver after discarding round 1). + // In the discard case, round 1's plan is unavailable and this round's + // plan wins by default. + name: "fts-like-fallback", + enabled: func(sv *variable.SessionVars) bool { + if !sv.EnableAlternativeLogicalPlans { + return false + } + return sv.StmtCtx.AlternativeLogicalPlanFTSLikeFallback || + sv.StmtCtx.AlternativeLogicalPlanHasPredicateContextMatch + }, + setup: func(sv *variable.SessionVars) { + sv.StmtCtx.AlternativeLogicalPlanFTSLikeFallback = true + }, + }, +} + func optimize(ctx context.Context, sctx planctx.PlanContext, node *resolve.NodeW, is infoschema.InfoSchema) (base.Plan, types.NameSlice, float64, error) { failpoint.Inject("checkOptimizeCountOne", func(val failpoint.Value) { // only count the optimization for SQL with specified text @@ -456,54 +712,158 @@ func optimize(ctx context.Context, sctx planctx.PlanContext, node *resolve.NodeW topsql.MockHighCPULoad(sctx.GetSessionVars().StmtCtx.OriginalSQL, sqlPrefixes, 10) }) sessVars := sctx.GetSessionVars() + var ( + beginOpt time.Time + optimizeStarted bool + ) + defer func() { + if optimizeStarted { + sessVars.DurationOptimizer.Total = time.Since(beginOpt) + } + }() - // build logical plan + // Build the logical plan from the raw AST. The hint processor only keeps + // AST-derived metadata; per-build state is allocated inside PlanBuilder. hintProcessor := hint.NewQBHintHandler(sctx.GetSessionVars().StmtCtx) node.Node.Accept(hintProcessor) - defer hintProcessor.HandleUnusedViewHints() - builder := planBuilderPool.Get().(*core.PlanBuilder) - defer planBuilderPool.Put(builder.ResetForReuse()) - builder.Init(sctx, is, hintProcessor) - p, err := buildLogicalPlan(ctx, sctx, node, builder) + + // build multi logical plan from raw AST. + var ( + needRestoreLogicalPlanCtx = sessVars.EnableAlternativeLogicalPlans + bestCost = math.MaxFloat64 + bestPlan base.PhysicalPlan + bestNames types.NameSlice + bestLogicalPlanCtx logicalPlanBuildCtx + checked bool + ) + var initialLogicalPlanCtx logicalPlanBuildCtx + if needRestoreLogicalPlanCtx { + initialLogicalPlanCtx = saveLogicalPlanBuildCtx(sessVars) + sessVars.StmtCtx.ResetAlternativeLogicalPlanSignals() + // Round 1 always uses the native FTSMysqlMatchAgainst builtin — same as + // the Alt-disabled default. The build records two signals on the + // planBuilder when MATCH...AGAINST is seen: + // * HasPredicateMatch: any direct-boolean-context MATCH. The round + // driver propagates this into stmtctx to trigger the + // fts-like-fallback alternative round, which builds a competing + // ILIKE-based plan; the cheaper of the two wins. + // * HasNonViableFTSMatch: a predicate-context MATCH whose native form + // cannot execute (no FTS index / no TiFlash replica / unsupported + // modifier). The round driver discards round 1's plan and forces + // AlternativeLogicalPlanFTSLikeFallback true so all subsequent + // rounds (correlate, etc.) re-rewrite with ILIKE. + } + + p, names, nonLogical, err := buildAndOptimizeLogicalPlanRound( + ctx, + sctx, + node, + is, + hintProcessor, + &checked, + &optimizeStarted, + &beginOpt, + needRestoreLogicalPlanCtx, + &bestPlan, + &bestNames, + &bestCost, + &bestLogicalPlanCtx, + nil, + ) if err != nil { return nil, nil, 0, err } + if nonLogical { + // keep compatible with the old. + return p, names, 0, nil + } - activeRoles := sessVars.ActiveRoles - // Check privilege. Maybe it's better to move this to the Preprocess, but - // we need the table information to check privilege, which is collected - // into the visitInfo in the logical plan builder. - if pm := privilege.GetPrivilegeManager(sctx); pm != nil { - visitInfo := core.VisitInfo4PrivCheck(ctx, is, node.Node, builder.GetVisitInfo()) - if err := core.CheckPrivilege(activeRoles, pm, visitInfo); err != nil { - return nil, nil, 0, err + // Pre-compute which rounds are enabled based on the signals from the first + // (default) build. This prevents signal leakage: alternative rounds rebuild + // the plan and may set AlternativeLogicalPlan* signals as a side effect, + // which are not reset by restoreLogicalPlanBuildCtx. Evaluating enabled() + // upfront ensures each round's eligibility is determined solely by the + // original build's signals. + enabledRounds := make([]alternativeRound, 0, len(alternativeRounds)) + for _, round := range alternativeRounds { + if round.enabled(sessVars) { + enabledRounds = append(enabledRounds, round) } } - - if err := core.CheckTableLock(sctx, is, builder.GetVisitInfo()); err != nil { - return nil, nil, 0, err + var lastAltRoundErr error + for _, round := range enabledRounds { + restoreLogicalPlanBuildCtx(sessVars, initialLogicalPlanCtx) + failpoint.Inject("failIfAlternativeLogicalPlanRoundTriggered", func(val failpoint.Value) { + if testSQL, ok := val.(string); ok && testSQL == node.Node.OriginalText() { + failpoint.Return(nil, nil, 0, errors.New("unexpected alternative logical plan round")) + } + }) + + // Use a closure so that defer-based cleanup runs at the end of each + // iteration, not at function exit. Keep per-round session snapshots on + // the closure stack instead of package globals so concurrent optimize + // calls do not race on restore values. + func() { + if round.setup != nil { + prevEnableCorrelateSubquery := sessVars.EnableCorrelateSubquery + prevFTSLikeFallback := sessVars.StmtCtx.AlternativeLogicalPlanFTSLikeFallback + defer func() { + if round.cleanup != nil { + round.cleanup(sessVars) + } + sessVars.EnableCorrelateSubquery = prevEnableCorrelateSubquery + sessVars.StmtCtx.AlternativeLogicalPlanFTSLikeFallback = prevFTSLikeFallback + }() + round.setup(sessVars) + } + p, names, nonLogical, err = buildAndOptimizeLogicalPlanRound( + ctx, + sctx, + node, + is, + hintProcessor, + &checked, + &optimizeStarted, + &beginOpt, + needRestoreLogicalPlanCtx, + &bestPlan, + &bestNames, + &bestCost, + &bestLogicalPlanCtx, + round.adjustFlag, + ) + }() + if err != nil { + // Alternative rounds are optional optimizations. If one fails, + // log and continue — the first round's plan is still valid in + // the general case. fts-like-fallback is the exception: the + // first round's plan may have been discarded as non-executable, + // so we remember the last alt-round error in case bestPlan + // remains nil after the loop. + logutil.BgLogger().Warn("alternative logical plan round failed", + zap.String("round", round.name), + zap.Error(err)) + lastAltRoundErr = err + continue + } + if nonLogical { + return p, names, 0, nil + } } - - if err := core.CheckTableMode(node); err != nil { - return nil, nil, 0, err + if bestPlan == nil { + if lastAltRoundErr != nil { + // No valid plan from any round. Surface the most recent alt-round + // error rather than the generic sentinel — typically this is the + // fts-like-fallback round reporting why MATCH...AGAINST cannot be + // rewritten (unsupported search string, etc.). + return nil, nil, 0, lastAltRoundErr + } + return nil, nil, 0, errors.New("failed to build logical plan") } - - names := p.OutputNames() - - // Handle the non-logical plan statement. - logic, isLogicalPlan := p.(base.LogicalPlan) - if !isLogicalPlan { - return p, names, 0, nil + if needRestoreLogicalPlanCtx { + restoreLogicalPlanBuildCtx(sessVars, bestLogicalPlanCtx) } - - core.RecheckCTE(logic) - - beginOpt := time.Now() - finalPlan, cost, err := core.DoOptimize(ctx, sctx, builder.GetOptFlag(), logic) - // TODO: capture plan replayer here if it matches sql and plan digest - - sessVars.DurationOptimizer.Total = time.Since(beginOpt) - return finalPlan, names, cost, err + return bestPlan, bestNames, bestCost, nil } // OptimizeExecStmt to handle the "execute" statement diff --git a/pkg/sessionctx/stmtctx/BUILD.bazel b/pkg/sessionctx/stmtctx/BUILD.bazel index d27a5532694bb..e205e2d94523e 100644 --- a/pkg/sessionctx/stmtctx/BUILD.bazel +++ b/pkg/sessionctx/stmtctx/BUILD.bazel @@ -44,10 +44,12 @@ go_test( ], embed = [":stmtctx"], flaky = True, - shard_count = 14, + shard_count = 16, deps = [ "//pkg/errctx", "//pkg/kv", + "//pkg/meta/model", + "//pkg/parser/ast", "//pkg/sessionctx/variable", "//pkg/testkit", "//pkg/testkit/testfailpoint", diff --git a/pkg/sessionctx/stmtctx/stmtctx.go b/pkg/sessionctx/stmtctx/stmtctx.go index c7a4f44689a82..16b356e46fcbf 100644 --- a/pkg/sessionctx/stmtctx/stmtctx.go +++ b/pkg/sessionctx/stmtctx/stmtctx.go @@ -69,6 +69,26 @@ func AllocateTaskID() uint64 { // SQLWarn relates a sql warning and it's level. type SQLWarn = contextutil.SQLWarn +// LogicalPlanBuildState stores the statement-scoped planner state that is mutated while +// building a logical plan from AST. +type LogicalPlanBuildState struct { + warnings []SQLWarn + extraWarnings []SQLWarn + tables []TableEntry + tableStats map[int64]any + lockTableIDs map[int64]struct{} + tblInfo2UnionScan map[*model.TableInfo]bool + useDynamicPruneMode bool + viewDepth int32 + colRefFromUpdatePlan intset.FastIntSet + // plan cache related stuff + planCacheUseCache bool + planCacheType contextutil.PlanCacheType + planCacheUnqualified string + planCacheForce bool + planCacheAlwaysWarn bool +} + // ReferenceCount indicates the reference count of StmtCtx. type ReferenceCount int32 @@ -452,6 +472,41 @@ type StatementContext struct { UseDynamicPruneMode bool // ColRefFromPlan mark the column ref used by assignment in update statement. ColRefFromUpdatePlan intset.FastIntSet + // AlternativeLogicalPlanDecorrelatedApply indicates whether the current logical + // optimization round decorrelated at least one Apply into Join. + AlternativeLogicalPlanDecorrelatedApply bool + // AlternativeLogicalPlanSameOrderIndexJoin indicates whether the current first + // round already produced a same-order index join candidate for a decorrelated Apply. + AlternativeLogicalPlanSameOrderIndexJoin bool + // AlternativeLogicalPlanOrderAwareJoinReorder indicates whether at least one + // logical build round produced an order-aware join reorder candidate that is + // worth exploring in a dedicated alternative round. + AlternativeLogicalPlanOrderAwareJoinReorder bool + // AlternativeLogicalPlanPreferCorrelate indicates whether the current logical + // build round encountered a non-correlated IN subquery eligible for the + // correlate-to-Apply alternative. + AlternativeLogicalPlanPreferCorrelate bool + // AlternativeLogicalPlanFTSLikeFallback is a mode flag controlling how the + // expression rewriter handles MATCH...AGAINST in predicate contexts. When + // false (the default, matching Alt-disabled behavior) the rewriter emits + // the native FTSMysqlMatchAgainst builtin. When true, the rewriter emits + // ILIKE-based predicates instead. + // + // Round 1 always runs with this flag false. The "fts-like-fallback" + // alternative round flips it to true (via its setup/cleanup) while it + // builds a competing ILIKE-based plan; the cost-cheapest plan wins via the + // normal alt-rounds cost comparison. If round 1's build records a + // predicate-context MATCH that cannot be served natively (no FTS index on a + // matched column / no TiFlash replica / modifier not pushdown-supported), + // optimize.go additionally invalidates round 1's plan and forces this flag + // true outside the round so any intervening rounds (correlate, etc.) also + // produce executable LIKE-based plans. + AlternativeLogicalPlanFTSLikeFallback bool + // AlternativeLogicalPlanHasPredicateContextMatch indicates that round 1 + // encountered a direct-boolean-context MATCH...AGAINST. The round driver + // uses this to enable the fts-like-fallback round for cost competition even + // when round 1's native plan is executable. + AlternativeLogicalPlanHasPredicateContextMatch bool // IsExplainAnalyzeDML is true if the statement is "explain analyze DML executors", before responding the explain // results to the client, the transaction should be committed first. See issue #37373 for more details. @@ -583,6 +638,80 @@ func (sc *StatementContext) Reset() bool { return true } +// SaveLogicalPlanBuildState captures the statement-scoped planner state before building +// another logical plan candidate from the same AST. +func (sc *StatementContext) SaveLogicalPlanBuildState() LogicalPlanBuildState { + planCacheUseCache, planCacheType, planCacheUnqualified, planCacheForce, planCacheAlwaysWarn := sc.PlanCacheTracker.Save() + return LogicalPlanBuildState{ + warnings: slices.Clone(sc.GetWarnings()), + extraWarnings: slices.Clone(sc.GetExtraWarnings()), + tables: slices.Clone(sc.Tables), + tableStats: maps.Clone(sc.TableStats), + lockTableIDs: maps.Clone(sc.LockTableIDs), + tblInfo2UnionScan: maps.Clone(sc.TblInfo2UnionScan), + useDynamicPruneMode: sc.UseDynamicPruneMode, + viewDepth: sc.ViewDepth, + colRefFromUpdatePlan: sc.ColRefFromUpdatePlan.Copy(), + planCacheUseCache: planCacheUseCache, + planCacheType: planCacheType, + planCacheUnqualified: planCacheUnqualified, + planCacheForce: planCacheForce, + planCacheAlwaysWarn: planCacheAlwaysWarn, + } +} + +// RestoreLogicalPlanBuildState restores the statement-scoped planner state after a +// discarded logical plan build attempt. +func (sc *StatementContext) RestoreLogicalPlanBuildState(state LogicalPlanBuildState) { + sc.SetWarnings(slices.Clone(state.warnings)) + sc.SetExtraWarnings(slices.Clone(state.extraWarnings)) + sc.Tables = slices.Clone(state.tables) + sc.TableStats = maps.Clone(state.tableStats) + sc.LockTableIDs = maps.Clone(state.lockTableIDs) + sc.TblInfo2UnionScan = maps.Clone(state.tblInfo2UnionScan) + sc.UseDynamicPruneMode = state.useDynamicPruneMode + sc.ViewDepth = state.viewDepth + sc.ColRefFromUpdatePlan.CopyFrom(state.colRefFromUpdatePlan) + sc.PlanCacheTracker.Restore(state.planCacheUseCache, state.planCacheType, state.planCacheUnqualified, state.planCacheForce, state.planCacheAlwaysWarn) + sc.RangeFallbackHandler = contextutil.NewRangeFallbackHandler(&sc.PlanCacheTracker, sc) +} + +// ResetAlternativeLogicalPlanSignals clears the statement-local signals used by the +// alternative logical plan feature. +func (sc *StatementContext) ResetAlternativeLogicalPlanSignals() { + sc.AlternativeLogicalPlanDecorrelatedApply = false + sc.AlternativeLogicalPlanSameOrderIndexJoin = false + sc.AlternativeLogicalPlanOrderAwareJoinReorder = false + sc.AlternativeLogicalPlanFTSLikeFallback = false + sc.AlternativeLogicalPlanHasPredicateContextMatch = false + sc.AlternativeLogicalPlanPreferCorrelate = false +} + +// MarkAlternativeLogicalPlanDecorrelatedApply records that at least one Apply has +// been decorrelated into a Join in the current round. +func (sc *StatementContext) MarkAlternativeLogicalPlanDecorrelatedApply() { + sc.AlternativeLogicalPlanDecorrelatedApply = true +} + +// MarkAlternativeLogicalPlanSameOrderIndexJoin records that the current first round +// has already produced a same-order index join candidate for a decorrelated Apply. +func (sc *StatementContext) MarkAlternativeLogicalPlanSameOrderIndexJoin() { + sc.AlternativeLogicalPlanSameOrderIndexJoin = true +} + +// MarkAlternativeLogicalPlanOrderAwareJoinReorder records that the current +// logical build round produced an order-aware join reorder candidate. +func (sc *StatementContext) MarkAlternativeLogicalPlanOrderAwareJoinReorder() { + sc.AlternativeLogicalPlanOrderAwareJoinReorder = true +} + +// MarkAlternativeLogicalPlanPreferCorrelate records that the current logical +// build round encountered a non-correlated IN subquery that is eligible for +// the correlate-to-Apply alternative. +func (sc *StatementContext) MarkAlternativeLogicalPlanPreferCorrelate() { + sc.AlternativeLogicalPlanPreferCorrelate = true +} + // CtxID returns the context id of the statement func (sc *StatementContext) CtxID() uint64 { return sc.ctxID diff --git a/pkg/sessionctx/stmtctx/stmtctx_test.go b/pkg/sessionctx/stmtctx/stmtctx_test.go index 7f5bf9b6008e1..79c3a91575176 100644 --- a/pkg/sessionctx/stmtctx/stmtctx_test.go +++ b/pkg/sessionctx/stmtctx/stmtctx_test.go @@ -27,6 +27,8 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/tidb/pkg/errctx" "github.com/pingcap/tidb/pkg/kv" + "github.com/pingcap/tidb/pkg/meta/model" + "github.com/pingcap/tidb/pkg/parser/ast" "github.com/pingcap/tidb/pkg/sessionctx/stmtctx" "github.com/pingcap/tidb/pkg/sessionctx/variable" "github.com/pingcap/tidb/pkg/testkit" @@ -218,6 +220,90 @@ func TestMarshalSQLWarn(t *testing.T) { tk.MustQuery("show warnings").Check(rows) } +func TestLogicalPlanBuildStateRestore(t *testing.T) { + sc := stmtctx.NewStmtCtx() + sc.AppendWarning(errors.New("baseline warning")) + sc.AppendExtraWarning(errors.New("baseline extra warning")) + sc.Tables = []stmtctx.TableEntry{{DB: "test", Table: "t"}} + sc.TableStats = map[int64]any{42: "baseline stats"} + sc.LockTableIDs = map[int64]struct{}{1: {}} + tblInfo := &model.TableInfo{ID: 42} + sc.TblInfo2UnionScan = map[*model.TableInfo]bool{tblInfo: true} + sc.UseDynamicPruneMode = true + sc.ViewDepth = 2 + sc.ColRefFromUpdatePlan.Insert(7) + sc.SetCacheType(contextutil.SessionNonPrepared) + sc.EnablePlanCache() + + state := sc.SaveLogicalPlanBuildState() + + sc.AppendWarning(errors.New("candidate warning")) + sc.AppendExtraWarning(errors.New("candidate extra warning")) + sc.Tables = []stmtctx.TableEntry{{DB: "candidate", Table: "t2"}} + sc.TableStats = map[int64]any{99: "candidate stats"} + sc.LockTableIDs[2] = struct{}{} + sc.TblInfo2UnionScan = map[*model.TableInfo]bool{{ID: 99}: false} + sc.UseDynamicPruneMode = false + sc.ViewDepth = 9 + sc.ColRefFromUpdatePlan.Insert(9) + sc.SetSkipPlanCache("candidate reason") + + sc.RestoreLogicalPlanBuildState(state) + + warnings := sc.GetWarnings() + require.Len(t, warnings, 1) + require.Equal(t, "baseline warning", warnings[0].Err.Error()) + + extraWarnings := sc.GetExtraWarnings() + require.Len(t, extraWarnings, 1) + require.Equal(t, "baseline extra warning", extraWarnings[0].Err.Error()) + + require.Equal(t, []stmtctx.TableEntry{{DB: "test", Table: "t"}}, sc.Tables) + require.Equal(t, map[int64]any{42: "baseline stats"}, sc.TableStats) + require.Equal(t, map[int64]struct{}{1: {}}, sc.LockTableIDs) + require.Equal(t, map[*model.TableInfo]bool{tblInfo: true}, sc.TblInfo2UnionScan) + require.True(t, sc.UseDynamicPartitionPrune()) + require.Equal(t, int32(2), sc.ViewDepth) + require.True(t, sc.ColRefFromUpdatePlan.Has(7)) + require.False(t, sc.ColRefFromUpdatePlan.Has(9)) + require.True(t, sc.UseCache()) + require.Empty(t, sc.PlanCacheUnqualified()) +} + +func TestQBHintHandlerBuildState(t *testing.T) { + handler := hint.NewQBHintHandler(nil) + handler.QBNameToSelOffset = map[string]int{"qb_1": 1} + handler.ViewQBNameToTable = map[string][]ast.HintTable{ + "view_qb": {{TableName: ast.NewCIStr("t")}}, + } + handler.ViewQBNameToHints = map[string][]*ast.TableOptimizerHint{ + "view_qb": {{HintName: ast.NewCIStr("merge_join")}}, + } + handler.Enter(&ast.SelectStmt{}) + handler.Enter(&ast.SelectStmt{}) + state := handler.NewBuildState() + hints := handler.GetCurrentStmtHints([]*ast.TableOptimizerHint{ + {HintName: ast.NewCIStr("use_index"), QBName: ast.NewCIStr("qb_1")}, + }, 1, state) + handler.MarkViewQBNameUsed("view_qb", state) + + require.Len(t, hints, 1) + require.Equal(t, "use_index", hints[0].HintName.L) + + require.Equal(t, 2, handler.MaxSelectStmtOffset()) + require.Equal(t, map[string]int{"qb_1": 1}, handler.QBNameToSelOffset) + require.Equal(t, map[string][]*ast.TableOptimizerHint{ + "view_qb": {{HintName: ast.NewCIStr("merge_join")}}, + }, handler.ViewQBNameToHints) + require.Equal(t, map[string][]ast.HintTable{ + "view_qb": {{TableName: ast.NewCIStr("t")}}, + }, handler.ViewQBNameToTable) + require.Equal(t, map[int][]*ast.TableOptimizerHint{ + 1: {{HintName: ast.NewCIStr("use_index"), QBName: ast.NewCIStr("qb_1")}}, + }, state.QBOffsetToHints) + require.Equal(t, map[string]struct{}{"view_qb": {}}, state.ViewQBNameUsed) +} + func TestApproxRuntimeInfo(t *testing.T) { var n = rand.Intn(19000) + 1000 var valRange = rand.Int31n(10000) + 1000 diff --git a/pkg/sessionctx/vardef/tidb_vars.go b/pkg/sessionctx/vardef/tidb_vars.go index d89f720d09721..07e409f7ae5be 100644 --- a/pkg/sessionctx/vardef/tidb_vars.go +++ b/pkg/sessionctx/vardef/tidb_vars.go @@ -334,6 +334,11 @@ const ( // TiDBOptEnableNoDecorrelateInSelect is used to control whether to enable the NO_DECORRELATE hint for subqueries in the select list. TiDBOptEnableNoDecorrelateInSelect = "tidb_opt_enable_no_decorrelate_in_select" + // TiDBOptEnableAlternativeLogicalPlans controls whether the optimizer may build + // an extra non-decorrelate logical alternative when decorrelation does not + // produce an equivalent same-order index join candidate. + TiDBOptEnableAlternativeLogicalPlans = "tidb_opt_enable_alternative_logical_plans" + // TiDBEnableSemiJoinRewrite controls automatic rewrite of semi-join to // inner-join with aggregation (equivalent to SEMI_JOIN_REWRITE() hint). TiDBOptEnableSemiJoinRewrite = "tidb_opt_enable_semi_join_rewrite" @@ -660,6 +665,9 @@ const ( // we'll choose a rather time-consuming algorithm to calculate the join order. TiDBOptJoinReorderThreshold = "tidb_opt_join_reorder_threshold" + // TiDBOptEnableAdvancedJoinReorder controls whether to use the advanced join reorder framework. + TiDBOptEnableAdvancedJoinReorder = "tidb_opt_enable_advanced_join_reorder" + // TiDBOptJoinReorderThroughSel enables pushing selection conditions down to // reordered join trees when applicable. TiDBOptJoinReorderThroughSel = "tidb_opt_join_reorder_through_sel" @@ -1450,6 +1458,7 @@ const ( DefOptInSubqToJoinAndAgg = true DefOptPreferRangeScan = true DefOptEnableNoDecorrelateInSelect = false + DefOptEnableAlternativeLogicalPlans = false DefOptEnableSemiJoinRewrite = false DefBatchInsert = false DefBatchDelete = false @@ -1519,6 +1528,7 @@ const ( DefEnableStrictDoubleTypeCheck = true DefEnableVectorizedExpression = true DefTiDBOptJoinReorderThreshold = 0 + DefTiDBOptEnableAdvancedJoinReorder = true DefTiDBOptJoinReorderThroughSel = false DefTiDBDDLSlowOprThreshold = 300 DefTiDBUseFastAnalyze = false diff --git a/pkg/sessionctx/variable/session.go b/pkg/sessionctx/variable/session.go index 478651a4c2c7f..01d5701416aae 100644 --- a/pkg/sessionctx/variable/session.go +++ b/pkg/sessionctx/variable/session.go @@ -1160,9 +1160,19 @@ type SessionVars struct { // EnableNoDecorrelateInSelect enables the NO_DECORRELATE hint for subqueries in the select list. EnableNoDecorrelateInSelect bool + // EnableAlternativeLogicalPlans enables building an extra non-decorrelate + // logical alternative when decorrelation does not produce an equivalent + // same-order index join candidate. + EnableAlternativeLogicalPlans bool + // EnableSemiJoinRewrite enables the SEMI_JOIN_REWRITE hint for subqueries in the where clause. EnableSemiJoinRewrite bool + // EnableCorrelateSubquery is an internal flag (not user-facing) toggled by the + // correlate alternative round to enable conversion of non-correlated semi-joins + // to correlated Apply during plan building. + EnableCorrelateSubquery bool + // AllowProjectionPushDown enables pushdown projection on TiKV. AllowProjectionPushDown bool @@ -1207,6 +1217,9 @@ type SessionVars struct { // to use the greedy join reorder algorithm. TiDBOptJoinReorderThreshold int + // TiDBOptEnableAdvancedJoinReorder controls whether to use the advanced join reorder framework. + TiDBOptEnableAdvancedJoinReorder bool + // TiDBOptJoinReorderThroughSel enables pushing selection conditions down to // reordered join trees when applicable. TiDBOptJoinReorderThroughSel bool @@ -2256,143 +2269,145 @@ func (connInfo *ConnectionInfo) IsSecureTransport() bool { // NewSessionVars creates a session vars object. func NewSessionVars(hctx HookContext) *SessionVars { vars := &SessionVars{ - UserVars: NewUserVars(), - systems: make(map[string]string), - PreparedStmts: make(map[uint32]any), - PreparedStmtNameToID: make(map[string]uint32), - PlanCacheParams: NewPlanCacheParamList(), - TxnCtx: &TransactionContext{}, - RetryInfo: &RetryInfo{}, - ActiveRoles: make([]*auth.RoleIdentity, 0, 10), - AutoIncrementIncrement: vardef.DefAutoIncrementIncrement, - AutoIncrementOffset: vardef.DefAutoIncrementOffset, - StmtCtx: stmtctx.NewStmtCtx(), - AllowAggPushDown: false, - AllowCartesianBCJ: vardef.DefOptCartesianBCJ, - MPPOuterJoinFixedBuildSide: vardef.DefOptMPPOuterJoinFixedBuildSide, - BroadcastJoinThresholdSize: vardef.DefBroadcastJoinThresholdSize, - BroadcastJoinThresholdCount: vardef.DefBroadcastJoinThresholdCount, - OptimizerSelectivityLevel: vardef.DefTiDBOptimizerSelectivityLevel, - OptIndexPruneThreshold: vardef.DefTiDBOptIndexPruneThreshold, - RiskScaleNDVSkewRatio: vardef.DefOptRiskScaleNDVSkewRatio, - RiskGroupNDVSkewRatio: vardef.DefOptRiskGroupNDVSkewRatio, - AlwaysKeepJoinKey: vardef.DefOptAlwaysKeepJoinKey, - CartesianJoinOrderThreshold: vardef.DefOptCartesianJoinOrderThreshold, - EnableOuterJoinReorder: vardef.DefTiDBEnableOuterJoinReorder, - EnableNoDecorrelateInSelect: vardef.DefOptEnableNoDecorrelateInSelect, - EnableSemiJoinRewrite: vardef.DefOptEnableSemiJoinRewrite, - RetryLimit: vardef.DefTiDBRetryLimit, - DisableTxnAutoRetry: vardef.DefTiDBDisableTxnAutoRetry, - DDLReorgPriority: kv.PriorityLow, - allowInSubqToJoinAndAgg: vardef.DefOptInSubqToJoinAndAgg, - preferRangeScan: vardef.DefOptPreferRangeScan, - EnableCorrelationAdjustment: vardef.DefOptEnableCorrelationAdjustment, - LimitPushDownThreshold: vardef.DefOptLimitPushDownThreshold, - CorrelationThreshold: vardef.DefOptCorrelationThreshold, - CorrelationExpFactor: vardef.DefOptCorrelationExpFactor, - RiskEqSkewRatio: vardef.DefOptRiskEqSkewRatio, - RiskRangeSkewRatio: vardef.DefOptRiskRangeSkewRatio, - cpuFactor: vardef.DefOptCPUFactor, - copCPUFactor: vardef.DefOptCopCPUFactor, - CopTiFlashConcurrencyFactor: vardef.DefOptTiFlashConcurrencyFactor, - networkFactor: vardef.DefOptNetworkFactor, - scanFactor: vardef.DefOptScanFactor, - descScanFactor: vardef.DefOptDescScanFactor, - seekFactor: vardef.DefOptSeekFactor, - memoryFactor: vardef.DefOptMemoryFactor, - diskFactor: vardef.DefOptDiskFactor, - concurrencyFactor: vardef.DefOptConcurrencyFactor, - IndexScanCostFactor: vardef.DefOptIndexScanCostFactor, - IndexReaderCostFactor: vardef.DefOptIndexReaderCostFactor, - TableReaderCostFactor: vardef.DefOptTableReaderCostFactor, - TableFullScanCostFactor: vardef.DefOptTableFullScanCostFactor, - TableRangeScanCostFactor: vardef.DefOptTableRangeScanCostFactor, - TableRowIDScanCostFactor: vardef.DefOptTableRowIDScanCostFactor, - TableTiFlashScanCostFactor: vardef.DefOptTableTiFlashScanCostFactor, - IndexLookupCostFactor: vardef.DefOptIndexLookupCostFactor, - IndexMergeCostFactor: vardef.DefOptIndexMergeCostFactor, - SortCostFactor: vardef.DefOptSortCostFactor, - TopNCostFactor: vardef.DefOptTopNCostFactor, - LimitCostFactor: vardef.DefOptLimitCostFactor, - StreamAggCostFactor: vardef.DefOptStreamAggCostFactor, - HashAggCostFactor: vardef.DefOptHashAggCostFactor, - MergeJoinCostFactor: vardef.DefOptMergeJoinCostFactor, - HashJoinCostFactor: vardef.DefOptHashJoinCostFactor, - IndexJoinCostFactor: vardef.DefOptIndexJoinCostFactor, - SelectivityFactor: vardef.DefOptSelectivityFactor, - enableForceInlineCTE: vardef.DefOptForceInlineCTE, - EnableVectorizedExpression: vardef.DefEnableVectorizedExpression, - CommandValue: uint32(mysql.ComSleep), - TiDBOptJoinReorderThreshold: vardef.DefTiDBOptJoinReorderThreshold, - TiDBOptJoinReorderThroughSel: vardef.DefTiDBOptJoinReorderThroughSel, - SlowQueryFile: config.GetGlobalConfig().Log.SlowQueryFile, - WaitSplitRegionFinish: vardef.DefTiDBWaitSplitRegionFinish, - WaitSplitRegionTimeout: vardef.DefWaitSplitRegionTimeout, - enableIndexMerge: vardef.DefTiDBEnableIndexMerge, - NoopFuncsMode: TiDBOptOnOffWarn(vardef.DefTiDBEnableNoopFuncs), - replicaRead: kv.ReplicaReadLeader, - AllowRemoveAutoInc: vardef.DefTiDBAllowRemoveAutoInc, - UsePlanBaselines: vardef.DefTiDBUsePlanBaselines, - EvolvePlanBaselines: vardef.DefTiDBEvolvePlanBaselines, - EnableExtendedStats: false, - IsolationReadEngines: make(map[kv.StoreType]struct{}), - LockWaitTimeout: vardef.DefInnodbLockWaitTimeout * 1000, - MetricSchemaStep: vardef.DefTiDBMetricSchemaStep, - MetricSchemaRangeDuration: vardef.DefTiDBMetricSchemaRangeDuration, - SequenceState: NewSequenceState(), - WindowingUseHighPrecision: true, - PrevFoundInPlanCache: vardef.DefTiDBFoundInPlanCache, - FoundInPlanCache: vardef.DefTiDBFoundInPlanCache, - PrevFoundInBinding: vardef.DefTiDBFoundInBinding, - FoundInBinding: vardef.DefTiDBFoundInBinding, - SelectLimit: math.MaxUint64, - AllowAutoRandExplicitInsert: vardef.DefTiDBAllowAutoRandExplicitInsert, - EnableClusteredIndex: vardef.DefTiDBEnableClusteredIndex, - EnableParallelApply: vardef.DefTiDBEnableParallelApply, - ShardAllocateStep: vardef.DefTiDBShardAllocateStep, - EnablePointGetCache: vardef.DefTiDBPointGetCache, - PartitionPruneMode: *atomic2.NewString(vardef.DefTiDBPartitionPruneMode), - TxnScope: kv.NewDefaultTxnScopeVar(), - EnabledRateLimitAction: vardef.DefTiDBEnableRateLimitAction, - EnableAsyncCommit: vardef.DefTiDBEnableAsyncCommit, - Enable1PC: vardef.DefTiDBEnable1PC, - GuaranteeLinearizability: vardef.DefTiDBGuaranteeLinearizability, - AnalyzeVersion: vardef.DefTiDBAnalyzeVersion, - EnableIndexMergeJoin: vardef.DefTiDBEnableIndexMergeJoin, - AllowFallbackToTiKV: make(map[kv.StoreType]struct{}), - CTEMaxRecursionDepth: vardef.DefCTEMaxRecursionDepth, - TMPTableSize: vardef.DefTiDBTmpTableMaxSize, - MPPStoreFailTTL: vardef.DefTiDBMPPStoreFailTTL, - Rng: mathutil.NewWithTime(), - EnableLegacyInstanceScope: vardef.DefEnableLegacyInstanceScope, - RemoveOrderbyInSubquery: vardef.DefTiDBRemoveOrderbyInSubquery, - EnableSkewDistinctAgg: vardef.DefTiDBSkewDistinctAgg, - Enable3StageDistinctAgg: vardef.DefTiDB3StageDistinctAgg, - MaxAllowedPacket: vardef.DefMaxAllowedPacket, - TiFlashFastScan: vardef.DefTiFlashFastScan, - EnableTiFlashReadForWriteStmt: true, - ForeignKeyChecks: vardef.DefTiDBForeignKeyChecks, - HookContext: hctx, - EnableReuseChunk: vardef.DefTiDBEnableReusechunk, - preUseChunkAlloc: vardef.DefTiDBUseAlloc, - chunkPool: nil, - mppExchangeCompressionMode: vardef.DefaultExchangeCompressionMode, - mppVersion: kv.MppVersionUnspecified, - EnableLateMaterialization: vardef.DefTiDBOptEnableLateMaterialization, - TiFlashComputeDispatchPolicy: tiflashcompute.DispatchPolicyConsistentHash, - ResourceGroupName: resourcegroup.DefaultResourceGroupName, - DefaultCollationForUTF8MB4: mysql.DefaultCollationName, - GroupConcatMaxLen: vardef.DefGroupConcatMaxLen, - EnableRedactLog: vardef.DefTiDBRedactLog, - EnableWindowFunction: vardef.DefEnableWindowFunction, - CostModelVersion: vardef.DefTiDBCostModelVer, - OptimizerEnableNAAJ: vardef.DefTiDBEnableNAAJ, - OptOrderingIdxSelRatio: vardef.DefTiDBOptOrderingIdxSelRatio, - RegardNULLAsPoint: vardef.DefTiDBRegardNULLAsPoint, - AllowProjectionPushDown: vardef.DefOptEnableProjectionPushDown, - SkipMissingPartitionStats: vardef.DefTiDBSkipMissingPartitionStats, - IndexLookUpPushDownPolicy: vardef.DefTiDBIndexLookUpPushDownPolicy, - OptPartialOrderedIndexForTopN: vardef.DefTiDBOptPartialOrderedIndexForTopN, + UserVars: NewUserVars(), + systems: make(map[string]string), + PreparedStmts: make(map[uint32]any), + PreparedStmtNameToID: make(map[string]uint32), + PlanCacheParams: NewPlanCacheParamList(), + TxnCtx: &TransactionContext{}, + RetryInfo: &RetryInfo{}, + ActiveRoles: make([]*auth.RoleIdentity, 0, 10), + AutoIncrementIncrement: vardef.DefAutoIncrementIncrement, + AutoIncrementOffset: vardef.DefAutoIncrementOffset, + StmtCtx: stmtctx.NewStmtCtx(), + AllowAggPushDown: false, + AllowCartesianBCJ: vardef.DefOptCartesianBCJ, + MPPOuterJoinFixedBuildSide: vardef.DefOptMPPOuterJoinFixedBuildSide, + BroadcastJoinThresholdSize: vardef.DefBroadcastJoinThresholdSize, + BroadcastJoinThresholdCount: vardef.DefBroadcastJoinThresholdCount, + OptimizerSelectivityLevel: vardef.DefTiDBOptimizerSelectivityLevel, + OptIndexPruneThreshold: vardef.DefTiDBOptIndexPruneThreshold, + RiskScaleNDVSkewRatio: vardef.DefOptRiskScaleNDVSkewRatio, + RiskGroupNDVSkewRatio: vardef.DefOptRiskGroupNDVSkewRatio, + AlwaysKeepJoinKey: vardef.DefOptAlwaysKeepJoinKey, + CartesianJoinOrderThreshold: vardef.DefOptCartesianJoinOrderThreshold, + EnableOuterJoinReorder: vardef.DefTiDBEnableOuterJoinReorder, + EnableNoDecorrelateInSelect: vardef.DefOptEnableNoDecorrelateInSelect, + EnableAlternativeLogicalPlans: vardef.DefOptEnableAlternativeLogicalPlans, + EnableSemiJoinRewrite: vardef.DefOptEnableSemiJoinRewrite, + RetryLimit: vardef.DefTiDBRetryLimit, + DisableTxnAutoRetry: vardef.DefTiDBDisableTxnAutoRetry, + DDLReorgPriority: kv.PriorityLow, + allowInSubqToJoinAndAgg: vardef.DefOptInSubqToJoinAndAgg, + preferRangeScan: vardef.DefOptPreferRangeScan, + EnableCorrelationAdjustment: vardef.DefOptEnableCorrelationAdjustment, + LimitPushDownThreshold: vardef.DefOptLimitPushDownThreshold, + CorrelationThreshold: vardef.DefOptCorrelationThreshold, + CorrelationExpFactor: vardef.DefOptCorrelationExpFactor, + RiskEqSkewRatio: vardef.DefOptRiskEqSkewRatio, + RiskRangeSkewRatio: vardef.DefOptRiskRangeSkewRatio, + cpuFactor: vardef.DefOptCPUFactor, + copCPUFactor: vardef.DefOptCopCPUFactor, + CopTiFlashConcurrencyFactor: vardef.DefOptTiFlashConcurrencyFactor, + networkFactor: vardef.DefOptNetworkFactor, + scanFactor: vardef.DefOptScanFactor, + descScanFactor: vardef.DefOptDescScanFactor, + seekFactor: vardef.DefOptSeekFactor, + memoryFactor: vardef.DefOptMemoryFactor, + diskFactor: vardef.DefOptDiskFactor, + concurrencyFactor: vardef.DefOptConcurrencyFactor, + IndexScanCostFactor: vardef.DefOptIndexScanCostFactor, + IndexReaderCostFactor: vardef.DefOptIndexReaderCostFactor, + TableReaderCostFactor: vardef.DefOptTableReaderCostFactor, + TableFullScanCostFactor: vardef.DefOptTableFullScanCostFactor, + TableRangeScanCostFactor: vardef.DefOptTableRangeScanCostFactor, + TableRowIDScanCostFactor: vardef.DefOptTableRowIDScanCostFactor, + TableTiFlashScanCostFactor: vardef.DefOptTableTiFlashScanCostFactor, + IndexLookupCostFactor: vardef.DefOptIndexLookupCostFactor, + IndexMergeCostFactor: vardef.DefOptIndexMergeCostFactor, + SortCostFactor: vardef.DefOptSortCostFactor, + TopNCostFactor: vardef.DefOptTopNCostFactor, + LimitCostFactor: vardef.DefOptLimitCostFactor, + StreamAggCostFactor: vardef.DefOptStreamAggCostFactor, + HashAggCostFactor: vardef.DefOptHashAggCostFactor, + MergeJoinCostFactor: vardef.DefOptMergeJoinCostFactor, + HashJoinCostFactor: vardef.DefOptHashJoinCostFactor, + IndexJoinCostFactor: vardef.DefOptIndexJoinCostFactor, + SelectivityFactor: vardef.DefOptSelectivityFactor, + enableForceInlineCTE: vardef.DefOptForceInlineCTE, + EnableVectorizedExpression: vardef.DefEnableVectorizedExpression, + CommandValue: uint32(mysql.ComSleep), + TiDBOptJoinReorderThreshold: vardef.DefTiDBOptJoinReorderThreshold, + TiDBOptEnableAdvancedJoinReorder: vardef.DefTiDBOptEnableAdvancedJoinReorder, + TiDBOptJoinReorderThroughSel: vardef.DefTiDBOptJoinReorderThroughSel, + SlowQueryFile: config.GetGlobalConfig().Log.SlowQueryFile, + WaitSplitRegionFinish: vardef.DefTiDBWaitSplitRegionFinish, + WaitSplitRegionTimeout: vardef.DefWaitSplitRegionTimeout, + enableIndexMerge: vardef.DefTiDBEnableIndexMerge, + NoopFuncsMode: TiDBOptOnOffWarn(vardef.DefTiDBEnableNoopFuncs), + replicaRead: kv.ReplicaReadLeader, + AllowRemoveAutoInc: vardef.DefTiDBAllowRemoveAutoInc, + UsePlanBaselines: vardef.DefTiDBUsePlanBaselines, + EvolvePlanBaselines: vardef.DefTiDBEvolvePlanBaselines, + EnableExtendedStats: false, + IsolationReadEngines: make(map[kv.StoreType]struct{}), + LockWaitTimeout: vardef.DefInnodbLockWaitTimeout * 1000, + MetricSchemaStep: vardef.DefTiDBMetricSchemaStep, + MetricSchemaRangeDuration: vardef.DefTiDBMetricSchemaRangeDuration, + SequenceState: NewSequenceState(), + WindowingUseHighPrecision: true, + PrevFoundInPlanCache: vardef.DefTiDBFoundInPlanCache, + FoundInPlanCache: vardef.DefTiDBFoundInPlanCache, + PrevFoundInBinding: vardef.DefTiDBFoundInBinding, + FoundInBinding: vardef.DefTiDBFoundInBinding, + SelectLimit: math.MaxUint64, + AllowAutoRandExplicitInsert: vardef.DefTiDBAllowAutoRandExplicitInsert, + EnableClusteredIndex: vardef.DefTiDBEnableClusteredIndex, + EnableParallelApply: vardef.DefTiDBEnableParallelApply, + ShardAllocateStep: vardef.DefTiDBShardAllocateStep, + EnablePointGetCache: vardef.DefTiDBPointGetCache, + PartitionPruneMode: *atomic2.NewString(vardef.DefTiDBPartitionPruneMode), + TxnScope: kv.NewDefaultTxnScopeVar(), + EnabledRateLimitAction: vardef.DefTiDBEnableRateLimitAction, + EnableAsyncCommit: vardef.DefTiDBEnableAsyncCommit, + Enable1PC: vardef.DefTiDBEnable1PC, + GuaranteeLinearizability: vardef.DefTiDBGuaranteeLinearizability, + AnalyzeVersion: vardef.DefTiDBAnalyzeVersion, + EnableIndexMergeJoin: vardef.DefTiDBEnableIndexMergeJoin, + AllowFallbackToTiKV: make(map[kv.StoreType]struct{}), + CTEMaxRecursionDepth: vardef.DefCTEMaxRecursionDepth, + TMPTableSize: vardef.DefTiDBTmpTableMaxSize, + MPPStoreFailTTL: vardef.DefTiDBMPPStoreFailTTL, + Rng: mathutil.NewWithTime(), + EnableLegacyInstanceScope: vardef.DefEnableLegacyInstanceScope, + RemoveOrderbyInSubquery: vardef.DefTiDBRemoveOrderbyInSubquery, + EnableSkewDistinctAgg: vardef.DefTiDBSkewDistinctAgg, + Enable3StageDistinctAgg: vardef.DefTiDB3StageDistinctAgg, + MaxAllowedPacket: vardef.DefMaxAllowedPacket, + TiFlashFastScan: vardef.DefTiFlashFastScan, + EnableTiFlashReadForWriteStmt: true, + ForeignKeyChecks: vardef.DefTiDBForeignKeyChecks, + HookContext: hctx, + EnableReuseChunk: vardef.DefTiDBEnableReusechunk, + preUseChunkAlloc: vardef.DefTiDBUseAlloc, + chunkPool: nil, + mppExchangeCompressionMode: vardef.DefaultExchangeCompressionMode, + mppVersion: kv.MppVersionUnspecified, + EnableLateMaterialization: vardef.DefTiDBOptEnableLateMaterialization, + TiFlashComputeDispatchPolicy: tiflashcompute.DispatchPolicyConsistentHash, + ResourceGroupName: resourcegroup.DefaultResourceGroupName, + DefaultCollationForUTF8MB4: mysql.DefaultCollationName, + GroupConcatMaxLen: vardef.DefGroupConcatMaxLen, + EnableRedactLog: vardef.DefTiDBRedactLog, + EnableWindowFunction: vardef.DefEnableWindowFunction, + CostModelVersion: vardef.DefTiDBCostModelVer, + OptimizerEnableNAAJ: vardef.DefTiDBEnableNAAJ, + OptOrderingIdxSelRatio: vardef.DefTiDBOptOrderingIdxSelRatio, + RegardNULLAsPoint: vardef.DefTiDBRegardNULLAsPoint, + AllowProjectionPushDown: vardef.DefOptEnableProjectionPushDown, + SkipMissingPartitionStats: vardef.DefTiDBSkipMissingPartitionStats, + IndexLookUpPushDownPolicy: vardef.DefTiDBIndexLookUpPushDownPolicy, + OptPartialOrderedIndexForTopN: vardef.DefTiDBOptPartialOrderedIndexForTopN, } vars.TiFlashFineGrainedShuffleBatchSize = vardef.DefTiFlashFineGrainedShuffleBatchSize vars.status.Store(uint32(mysql.ServerStatusAutocommit)) diff --git a/pkg/sessionctx/variable/setvar_affect.go b/pkg/sessionctx/variable/setvar_affect.go index c9e92d396e865..258de00d355dd 100644 --- a/pkg/sessionctx/variable/setvar_affect.go +++ b/pkg/sessionctx/variable/setvar_affect.go @@ -98,6 +98,7 @@ var isHintUpdatableVerified = map[string]struct{}{ "tidb_opt_projection_push_down": {}, "tidb_enable_vectorized_expression": {}, "tidb_opt_join_reorder_threshold": {}, + "tidb_opt_enable_advanced_join_reorder": {}, "tidb_enable_index_merge": {}, "tidb_enable_extended_stats": {}, "tidb_isolation_read_engines": {}, @@ -120,6 +121,7 @@ var isHintUpdatableVerified = map[string]struct{}{ "mpp_version": {}, "tidb_enable_inl_join_inner_multi_pattern": {}, "tidb_opt_enable_no_decorrelate_in_select": {}, + "tidb_opt_enable_alternative_logical_plans": {}, "tidb_opt_enable_late_materialization": {}, "tidb_opt_ordering_index_selectivity_threshold": {}, "tidb_opt_ordering_index_selectivity_ratio": {}, diff --git a/pkg/sessionctx/variable/sysvar.go b/pkg/sessionctx/variable/sysvar.go index 34fb0575b4073..30c208c38e0e5 100644 --- a/pkg/sessionctx/variable/sysvar.go +++ b/pkg/sessionctx/variable/sysvar.go @@ -2546,6 +2546,10 @@ var defaultSysVars = []*SysVar{ s.EnableNoDecorrelateInSelect = TiDBOptOn(val) return nil }}, + {Scope: vardef.ScopeGlobal | vardef.ScopeSession, Name: vardef.TiDBOptEnableAlternativeLogicalPlans, Value: BoolToOnOff(vardef.DefOptEnableAlternativeLogicalPlans), Type: vardef.TypeBool, SetSession: func(s *SessionVars, val string) error { + s.EnableAlternativeLogicalPlans = TiDBOptOn(val) + return nil + }}, {Scope: vardef.ScopeGlobal | vardef.ScopeSession, Name: vardef.TiDBEnableStrictDoubleTypeCheck, Value: BoolToOnOff(vardef.DefEnableStrictDoubleTypeCheck), Type: vardef.TypeBool, SetSession: func(s *SessionVars, val string) error { s.EnableStrictDoubleTypeCheck = TiDBOptOn(val) return nil @@ -2614,6 +2618,10 @@ var defaultSysVars = []*SysVar{ s.TiDBOptJoinReorderThreshold = tidbOptPositiveInt32(val, vardef.DefTiDBOptJoinReorderThreshold) return nil }}, + {Scope: vardef.ScopeGlobal | vardef.ScopeSession, Name: vardef.TiDBOptEnableAdvancedJoinReorder, Value: BoolToOnOff(vardef.DefTiDBOptEnableAdvancedJoinReorder), Type: vardef.TypeBool, SetSession: func(s *SessionVars, val string) error { + s.TiDBOptEnableAdvancedJoinReorder = TiDBOptOn(val) + return nil + }}, {Scope: vardef.ScopeGlobal | vardef.ScopeSession, Name: vardef.TiDBOptJoinReorderThroughSel, Value: BoolToOnOff(vardef.DefTiDBOptJoinReorderThroughSel), Type: vardef.TypeBool, SetSession: func(s *SessionVars, val string) error { s.TiDBOptJoinReorderThroughSel = TiDBOptOn(val) return nil diff --git a/pkg/sessionctx/variable/varsutil_test.go b/pkg/sessionctx/variable/varsutil_test.go index 163ddd1872240..6e802a757d3d1 100644 --- a/pkg/sessionctx/variable/varsutil_test.go +++ b/pkg/sessionctx/variable/varsutil_test.go @@ -91,6 +91,7 @@ func TestNewSessionVars(t *testing.T) { require.Equal(t, vardef.DefTiDBAnalyzeVersion, vars.AnalyzeVersion) require.Equal(t, vardef.DefCTEMaxRecursionDepth, vars.CTEMaxRecursionDepth) require.Equal(t, int64(vardef.DefTiDBTmpTableMaxSize), vars.TMPTableSize) + require.Equal(t, vardef.DefOptEnableAlternativeLogicalPlans, vars.EnableAlternativeLogicalPlans) assertFieldsGreaterThanZero(t, reflect.ValueOf(vars.MemQuota)) assertFieldsGreaterThanZero(t, reflect.ValueOf(vars.BatchSize)) @@ -210,6 +211,11 @@ func TestVarsutil(t *testing.T) { require.NoError(t, err) require.True(t, v.BatchInsert) + require.False(t, v.EnableAlternativeLogicalPlans) + err = v.SetSystemVar(vardef.TiDBOptEnableAlternativeLogicalPlans, "1") + require.NoError(t, err) + require.True(t, v.EnableAlternativeLogicalPlans) + require.Equal(t, 32, v.InitChunkSize) require.Equal(t, 1024, v.MaxChunkSize) err = v.SetSystemVar(vardef.TiDBMaxChunkSize, "2") @@ -264,6 +270,14 @@ func TestVarsutil(t *testing.T) { require.Equal(t, "5", val) require.Equal(t, 5, v.TiDBOptJoinReorderThreshold) + require.Equal(t, vardef.DefTiDBOptEnableAdvancedJoinReorder, v.TiDBOptEnableAdvancedJoinReorder) + err = v.SetSystemVar(vardef.TiDBOptEnableAdvancedJoinReorder, "OFF") + require.NoError(t, err) + require.Equal(t, false, v.TiDBOptEnableAdvancedJoinReorder) + err = v.SetSystemVar(vardef.TiDBOptEnableAdvancedJoinReorder, "ON") + require.NoError(t, err) + require.Equal(t, true, v.TiDBOptEnableAdvancedJoinReorder) + err = v.SetSystemVar(vardef.TiDBLowResolutionTSO, "1") require.NoError(t, err) val, err = v.GetSessionOrGlobalSystemVar(context.Background(), vardef.TiDBLowResolutionTSO) diff --git a/pkg/tici/BUILD.bazel b/pkg/tici/BUILD.bazel index 9e7b5159018af..33f1ab80d4d49 100644 --- a/pkg/tici/BUILD.bazel +++ b/pkg/tici/BUILD.bazel @@ -53,7 +53,7 @@ go_test( ], embed = [":tici"], flaky = True, - shard_count = 27, + shard_count = 30, deps = [ "//pkg/kv", "//pkg/lightning/membuf", diff --git a/pkg/util/context/plancache.go b/pkg/util/context/plancache.go index 9cac5ec81012e..d6c46cd4db81e 100644 --- a/pkg/util/context/plancache.go +++ b/pkg/util/context/plancache.go @@ -122,6 +122,26 @@ func (h *PlanCacheTracker) EnablePlanCache() { h.useCache = true } +// Save captures the mutable planning-time state of the tracker. +func (h *PlanCacheTracker) Save() (useCache bool, cacheType PlanCacheType, planCacheUnqualified string, forcePlanCache bool, alwaysWarnSkipCache bool) { + h.mu.Lock() + defer h.mu.Unlock() + + return h.useCache, h.cacheType, h.planCacheUnqualified, h.forcePlanCache, h.alwaysWarnSkipCache +} + +// Restore restores the mutable planning-time state of the tracker. +func (h *PlanCacheTracker) Restore(useCache bool, cacheType PlanCacheType, planCacheUnqualified string, forcePlanCache bool, alwaysWarnSkipCache bool) { + h.mu.Lock() + defer h.mu.Unlock() + + h.useCache = useCache + h.cacheType = cacheType + h.planCacheUnqualified = planCacheUnqualified + h.forcePlanCache = forcePlanCache + h.alwaysWarnSkipCache = alwaysWarnSkipCache +} + // UseCache returns whether to use plan cache. func (h *PlanCacheTracker) UseCache() bool { h.mu.Lock() diff --git a/pkg/util/hint/hint_query_block.go b/pkg/util/hint/hint_query_block.go index eb85910b59827..0262e1b53e6a3 100644 --- a/pkg/util/hint/hint_query_block.go +++ b/pkg/util/hint/hint_query_block.go @@ -30,18 +30,23 @@ import ( // In both cases, the `use_index` hint doesn't take effect directly, since a specific qb_name is specified, and this // QBHintHandler is used to handle this cases. type QBHintHandler struct { - QBNameToSelOffset map[string]int // map[QBName]SelectOffset - QBOffsetToHints map[int][]*ast.TableOptimizerHint // map[QueryBlockOffset]Hints + QBNameToSelOffset map[string]int // map[QBName]SelectOffset // Used for the view's hint ViewQBNameToTable map[string][]ast.HintTable // map[QBName]HintedTable ViewQBNameToHints map[string][]*ast.TableOptimizerHint // map[QBName]Hints - ViewQBNameUsed map[string]struct{} // map[QBName]Used warnHandler hintWarnHandler selectStmtOffset int } +// QBHintBuildState stores the per-build runtime state for a QBHintHandler. +// The handler itself only keeps AST-derived metadata and can be shared safely. +type QBHintBuildState struct { + QBOffsetToHints map[int][]*ast.TableOptimizerHint // map[QueryBlockOffset]Hints + ViewQBNameUsed map[string]struct{} // map[QBName]Used +} + // hintWarnHandler is used to handle the warning when parsing hints. type hintWarnHandler interface { SetHintWarning(warn string) @@ -55,6 +60,20 @@ func NewQBHintHandler(warnHandler hintWarnHandler) *QBHintHandler { } } +// NewBuildState creates the per-build runtime state for the handler. +func (p *QBHintHandler) NewBuildState() *QBHintBuildState { + if p == nil { + return nil + } + + state := &QBHintBuildState{} + if len(p.ViewQBNameToTable) == 0 { + return state + } + state.ViewQBNameUsed = make(map[string]struct{}, len(p.ViewQBNameToTable)) + return state +} + // MaxSelectStmtOffset returns the current stmt offset. func (p *QBHintHandler) MaxSelectStmtOffset() int { return p.selectStmtOffset @@ -132,7 +151,6 @@ func (p *QBHintHandler) handleViewHints(hints []*ast.TableOptimizerHint, offset usedHints[i] = true if p.ViewQBNameToTable == nil { p.ViewQBNameToTable = make(map[string][]ast.HintTable) - p.ViewQBNameUsed = make(map[string]struct{}) } qbName := hint.QBName.L if qbName == "" { @@ -201,15 +219,21 @@ func (p *QBHintHandler) handleViewHints(hints []*ast.TableOptimizerHint, offset } // HandleUnusedViewHints handle the unused view hints. -func (p *QBHintHandler) HandleUnusedViewHints() { +func (p *QBHintHandler) HandleUnusedViewHints(state *QBHintBuildState, warn []string) []string { + if state == nil { + return warn + } + + warn = warn[:0] if p.ViewQBNameToTable != nil { for qbName := range p.ViewQBNameToTable { - _, ok := p.ViewQBNameUsed[qbName] + _, ok := state.ViewQBNameUsed[qbName] if !ok && p.warnHandler != nil { - p.warnHandler.SetHintWarning(fmt.Sprintf("The qb_name hint %s is unused, please check whether the table list in the qb_name hint %s is correct", qbName, qbName)) + warn = append(warn, fmt.Sprintf("The qb_name hint %s is unused, please check whether the table list in the qb_name hint %s is correct", qbName, qbName)) } } } + return warn } const ( @@ -242,6 +266,16 @@ func (p *QBHintHandler) getBlockOffset(blockName ast.CIStr) int { return -1 } +// SetWarns set the warning from a list of strings. +func (p *QBHintHandler) SetWarns(warns []string) { + if p == nil || p.warnHandler == nil || len(warns) == 0 { + return + } + for _, one := range warns { + p.warnHandler.SetHintWarning(one) + } +} + // GetHintOffset gets the offset of stmt that the hints take effects. func (p *QBHintHandler) GetHintOffset(qbName ast.CIStr, currentOffset int) int { if qbName.L != "" { @@ -279,9 +313,12 @@ func (p *QBHintHandler) isHint4View(hint *ast.TableOptimizerHint) bool { } // GetCurrentStmtHints extracts all hints that take effects at current stmt. -func (p *QBHintHandler) GetCurrentStmtHints(hints []*ast.TableOptimizerHint, currentOffset int) []*ast.TableOptimizerHint { - if p.QBOffsetToHints == nil { - p.QBOffsetToHints = make(map[int][]*ast.TableOptimizerHint) +func (p *QBHintHandler) GetCurrentStmtHints(hints []*ast.TableOptimizerHint, currentOffset int, state *QBHintBuildState) []*ast.TableOptimizerHint { + if state == nil { + state = &QBHintBuildState{} + } + if state.QBOffsetToHints == nil { + state.QBOffsetToHints = make(map[int][]*ast.TableOptimizerHint) } for _, hint := range hints { if hint.HintName.L == hintQBName { @@ -295,11 +332,19 @@ func (p *QBHintHandler) GetCurrentStmtHints(hints []*ast.TableOptimizerHint, cur } continue } - if !slices.Contains(p.QBOffsetToHints[offset], hint) { - p.QBOffsetToHints[offset] = append(p.QBOffsetToHints[offset], hint) + if !slices.Contains(state.QBOffsetToHints[offset], hint) { + state.QBOffsetToHints[offset] = append(state.QBOffsetToHints[offset], hint) } } - return p.QBOffsetToHints[currentOffset] + return state.QBOffsetToHints[currentOffset] +} + +// MarkViewQBNameUsed records that the named view qb hint was used in the current build. +func (*QBHintHandler) MarkViewQBNameUsed(qbName string, state *QBHintBuildState) { + if state == nil || state.ViewQBNameUsed == nil { + return + } + state.ViewQBNameUsed[qbName] = struct{}{} } // GenerateQBName builds QBName from offset. diff --git a/tests/integrationtest/r/planner/core/casetest/index/index.result b/tests/integrationtest/r/planner/core/casetest/index/index.result index c9e60899bb74b..97996f0eb9070 100644 --- a/tests/integrationtest/r/planner/core/casetest/index/index.result +++ b/tests/integrationtest/r/planner/core/casetest/index/index.result @@ -554,7 +554,7 @@ IndexJoin root inner join, inner:IndexLookUp, outer key:planner__core__casetest │ └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo └─IndexLookUp(Probe) root ├─Selection(Build) cop[tikv] not(isnull(planner__core__casetest__index__index.t1.a)), not(isnull(planner__core__casetest__index__index.t1.b)) - │ └─IndexRangeScan cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range: decided by [eq(planner__core__casetest__index__index.t1.a, planner__core__casetest__index__index.t2.e) lt(planner__core__casetest__index__index.t1.b, plus(planner__core__casetest__index__index.t2.f, 10)) gt(planner__core__casetest__index__index.t1.b, planner__core__casetest__index__index.t2.f)], keep order:false, stats:pseudo + │ └─IndexRangeScan cop[tikv] table:t1, index:idx_a_b_c_d(a, b, c, d) range: decided by [eq(planner__core__casetest__index__index.t1.a, planner__core__casetest__index__index.t2.e) gt(planner__core__casetest__index__index.t1.b, planner__core__casetest__index__index.t2.f) lt(planner__core__casetest__index__index.t1.b, plus(planner__core__casetest__index__index.t2.f, 10))], keep order:false, stats:pseudo └─TableRowIDScan(Probe) cop[tikv] table:t1 keep order:false, stats:pseudo show warnings; Level Code Message diff --git a/tests/integrationtest/r/planner/core/casetest/rule/rule_join_reorder.result b/tests/integrationtest/r/planner/core/casetest/rule/rule_join_reorder.result index 2b7972ed7aaf5..bcb53b01e01bb 100644 --- a/tests/integrationtest/r/planner/core/casetest/rule/rule_join_reorder.result +++ b/tests/integrationtest/r/planner/core/casetest/rule/rule_join_reorder.result @@ -893,8 +893,6 @@ HashJoin root CARTESIAN inner join └─TableReader(Probe) root data:Selection └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo -Level Code Message -Warning 1815 leading hint is inapplicable, check if the leading hint table has join conditions with other tables explain format='plan_tree' select /*+ leading(t2, t1, t3) */ * from t, t1, t2, t3 where t.a = t1.a and t1.b=t2.b; id task access object operator info Projection root planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b @@ -1104,8 +1102,6 @@ HashJoin root CARTESIAN inner join └─TableReader(Probe) root data:Selection └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)) └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo -Level Code Message -Warning 1815 leading hint is inapplicable, check if the leading hint table has join conditions with other tables explain format='plan_tree' select /*+ leading(t1) */ * from t2 join (t1 join t3 on t1.a=t3.a) on t2.a=1; id task access object operator info Projection root planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b @@ -1175,8 +1171,6 @@ Projection root planner__core__casetest__rule__rule_join_reorder.t2.a, planner_ └─TableReader(Probe) root data:Selection └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)) └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo -Level Code Message -Warning 1815 leading hint is inapplicable, check if the leading hint table has join conditions with other tables explain format='plan_tree' select /*+ leading(t2, t1, t3) */ * from t2 join (t1 join t3 on t1.a=t3.a) on t2.a=1; id task access object operator info HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t3.a)] @@ -2984,23 +2978,22 @@ HashJoin root left outer join, left side:PartitionUnion, equal:[eq(planner__cor └─TableFullScan cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo Level Code Message Warning 1815 leading hint is inapplicable, check if the leading hint table is valid -Warning 1815 leading hint is inapplicable, check if the leading hint table is valid explain format='plan_tree' select /*+ leading(t2, t3) */ * from t2 left join (t1 join t3 on t1.a=t3.a join t4 on t3.b = t4.b) on t2.b=t1.b; id task access object operator info -HashJoin root left outer join, left side:PartitionUnion, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.b)] -├─PartitionUnion(Build) root -│ ├─TableReader root data:TableFullScan -│ │ └─TableFullScan cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo -│ ├─TableReader root data:TableFullScan -│ │ └─TableFullScan cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo -│ ├─TableReader root data:TableFullScan -│ │ └─TableFullScan cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo -│ ├─TableReader root data:TableFullScan -│ │ └─TableFullScan cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo -│ └─TableReader root data:TableFullScan -│ └─TableFullScan cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo -└─Projection(Probe) root planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b - └─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.b)] +Projection root planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b +└─HashJoin root left outer join, left side:PartitionUnion, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.b)] + ├─PartitionUnion(Build) root + │ ├─TableReader root data:TableFullScan + │ │ └─TableFullScan cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo + │ ├─TableReader root data:TableFullScan + │ │ └─TableFullScan cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo + │ ├─TableReader root data:TableFullScan + │ │ └─TableFullScan cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo + │ ├─TableReader root data:TableFullScan + │ │ └─TableFullScan cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo + │ └─TableReader root data:TableFullScan + │ └─TableFullScan cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.b)] ├─PartitionUnion(Build) root │ ├─TableReader root data:Selection │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) @@ -3040,23 +3033,22 @@ HashJoin root left outer join, left side:PartitionUnion, equal:[eq(planner__cor └─TableFullScan cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo Level Code Message Warning 1815 leading hint is inapplicable, check if the leading hint table is valid -Warning 1815 leading hint is inapplicable, check if the leading hint table is valid explain format='plan_tree' select /*+ leading(t3, t4) */ * from t2 left join (t1 join t3 on t1.a=t3.a join t4 on t3.b = t4.b) on t2.b=t1.b; id task access object operator info -HashJoin root left outer join, left side:PartitionUnion, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.b)] -├─PartitionUnion(Build) root -│ ├─TableReader root data:TableFullScan -│ │ └─TableFullScan cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo -│ ├─TableReader root data:TableFullScan -│ │ └─TableFullScan cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo -│ ├─TableReader root data:TableFullScan -│ │ └─TableFullScan cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo -│ ├─TableReader root data:TableFullScan -│ │ └─TableFullScan cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo -│ └─TableReader root data:TableFullScan -│ └─TableFullScan cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo -└─Projection(Probe) root planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b - └─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.b)] +Projection root planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b +└─HashJoin root left outer join, left side:PartitionUnion, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.b)] + ├─PartitionUnion(Build) root + │ ├─TableReader root data:TableFullScan + │ │ └─TableFullScan cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo + │ ├─TableReader root data:TableFullScan + │ │ └─TableFullScan cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo + │ ├─TableReader root data:TableFullScan + │ │ └─TableFullScan cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo + │ ├─TableReader root data:TableFullScan + │ │ └─TableFullScan cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo + │ └─TableReader root data:TableFullScan + │ └─TableFullScan cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.b)] ├─PartitionUnion(Build) root │ ├─TableReader root data:Selection │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) @@ -3099,485 +3091,478 @@ Warning 1815 leading hint is inapplicable, check if the leading hint table is va explain format='plan_tree' select /*+ leading(t3, t4) */ * from t2 left join (t1 join t3 on t1.a=t3.a join t4 on t3.b = t4.b) on t2.b=t1.b join t5 on t2.a = t5.a join t6 on t5.b=t6.b; id task access object operator info Projection root planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b, planner__core__casetest__rule__rule_join_reorder.t5.a, planner__core__casetest__rule__rule_join_reorder.t5.b, planner__core__casetest__rule__rule_join_reorder.t6.a, planner__core__casetest__rule__rule_join_reorder.t6.b -└─HashJoin root left outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.b)] - ├─Projection(Build) root planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b - │ └─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.b)] - │ ├─PartitionUnion(Build) root - │ │ ├─TableReader root data:Selection - │ │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) - │ │ │ └─TableFullScan cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo - │ │ ├─TableReader root data:Selection - │ │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) - │ │ │ └─TableFullScan cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo - │ │ ├─TableReader root data:Selection - │ │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) - │ │ │ └─TableFullScan cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo - │ │ └─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) - │ │ └─TableFullScan cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo - │ └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] - │ ├─PartitionUnion(Build) root - │ │ ├─TableReader root data:Selection - │ │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ │ │ └─TableFullScan cop[tikv] table:t3, partition:p0 keep order:false, stats:pseudo - │ │ ├─TableReader root data:Selection - │ │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ │ │ └─TableFullScan cop[tikv] table:t3, partition:p1 keep order:false, stats:pseudo - │ │ └─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ │ └─TableFullScan cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo - │ └─PartitionUnion(Probe) root - │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ │ └─TableFullScan cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo - │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ │ └─TableFullScan cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo - │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ │ └─TableFullScan cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo - │ └─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ └─TableFullScan cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo - └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t5.a, planner__core__casetest__rule__rule_join_reorder.t2.a)] +└─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t5.b, planner__core__casetest__rule__rule_join_reorder.t6.b)] + ├─PartitionUnion(Build) root + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t6.b)) + │ │ └─TableFullScan cop[tikv] table:t6, partition:p0 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t6.b)) + │ │ └─TableFullScan cop[tikv] table:t6, partition:p1 keep order:false, stats:pseudo + │ └─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t6.b)) + │ └─TableFullScan cop[tikv] table:t6, partition:p2 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t5.a)] ├─PartitionUnion(Build) root │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) - │ │ └─TableFullScan cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) + │ │ └─TableFullScan cop[tikv] table:t5, partition:p0 keep order:false, stats:pseudo │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) - │ │ └─TableFullScan cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) + │ │ └─TableFullScan cop[tikv] table:t5, partition:p1 keep order:false, stats:pseudo │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) - │ │ └─TableFullScan cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) + │ │ └─TableFullScan cop[tikv] table:t5, partition:p2 keep order:false, stats:pseudo │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) - │ │ └─TableFullScan cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) + │ │ └─TableFullScan cop[tikv] table:t5, partition:p3 keep order:false, stats:pseudo │ └─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) - │ └─TableFullScan cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo - └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t6.b, planner__core__casetest__rule__rule_join_reorder.t5.b)] + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) + │ └─TableFullScan cop[tikv] table:t5, partition:p4 keep order:false, stats:pseudo + └─HashJoin(Probe) root left outer join, left side:PartitionUnion, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.b)] ├─PartitionUnion(Build) root │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t6.b)) - │ │ └─TableFullScan cop[tikv] table:t6, partition:p0 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) + │ │ └─TableFullScan cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) + │ │ └─TableFullScan cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) + │ │ └─TableFullScan cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t6.b)) - │ │ └─TableFullScan cop[tikv] table:t6, partition:p1 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) + │ │ └─TableFullScan cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo │ └─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t6.b)) - │ └─TableFullScan cop[tikv] table:t6, partition:p2 keep order:false, stats:pseudo - └─PartitionUnion(Probe) root - ├─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) - │ └─TableFullScan cop[tikv] table:t5, partition:p0 keep order:false, stats:pseudo - ├─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) - │ └─TableFullScan cop[tikv] table:t5, partition:p1 keep order:false, stats:pseudo - ├─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) - │ └─TableFullScan cop[tikv] table:t5, partition:p2 keep order:false, stats:pseudo - ├─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) - │ └─TableFullScan cop[tikv] table:t5, partition:p3 keep order:false, stats:pseudo - └─TableReader root data:Selection - └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) - └─TableFullScan cop[tikv] table:t5, partition:p4 keep order:false, stats:pseudo + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) + │ └─TableFullScan cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.b)] + ├─PartitionUnion(Build) root + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) + │ │ └─TableFullScan cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) + │ │ └─TableFullScan cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) + │ │ └─TableFullScan cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo + │ └─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) + │ └─TableFullScan cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] + ├─PartitionUnion(Build) root + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ │ └─TableFullScan cop[tikv] table:t3, partition:p0 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ │ └─TableFullScan cop[tikv] table:t3, partition:p1 keep order:false, stats:pseudo + │ └─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ └─TableFullScan cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo + └─PartitionUnion(Probe) root + ├─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ └─TableFullScan cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo + ├─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ └─TableFullScan cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo + ├─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ └─TableFullScan cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo + └─TableReader root data:Selection + └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + └─TableFullScan cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo Level Code Message Warning 1815 leading hint is inapplicable, check if the leading hint table is valid explain format='plan_tree' select /*+ leading(t3, t4) leading(t5, t6) */ * from t2 left join (t1 join t3 on t1.a=t3.a join t4 on t3.b = t4.b) on t2.b=t1.b join t5 on t2.a = t5.a join t6 on t5.b=t6.b; id task access object operator info Projection root planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b, planner__core__casetest__rule__rule_join_reorder.t5.a, planner__core__casetest__rule__rule_join_reorder.t5.b, planner__core__casetest__rule__rule_join_reorder.t6.a, planner__core__casetest__rule__rule_join_reorder.t6.b -└─HashJoin root left outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.b)] - ├─Projection(Build) root planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b - │ └─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.b)] - │ ├─PartitionUnion(Build) root - │ │ ├─TableReader root data:Selection - │ │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) - │ │ │ └─TableFullScan cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo - │ │ ├─TableReader root data:Selection - │ │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) - │ │ │ └─TableFullScan cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo - │ │ ├─TableReader root data:Selection - │ │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) - │ │ │ └─TableFullScan cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo - │ │ └─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) - │ │ └─TableFullScan cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo - │ └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] - │ ├─PartitionUnion(Build) root - │ │ ├─TableReader root data:Selection - │ │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ │ │ └─TableFullScan cop[tikv] table:t3, partition:p0 keep order:false, stats:pseudo - │ │ ├─TableReader root data:Selection - │ │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ │ │ └─TableFullScan cop[tikv] table:t3, partition:p1 keep order:false, stats:pseudo - │ │ └─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ │ └─TableFullScan cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo - │ └─PartitionUnion(Probe) root - │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ │ └─TableFullScan cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo - │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ │ └─TableFullScan cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo - │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ │ └─TableFullScan cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo - │ └─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ └─TableFullScan cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo - └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t5.a, planner__core__casetest__rule__rule_join_reorder.t2.a)] +└─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t5.b, planner__core__casetest__rule__rule_join_reorder.t6.b)] + ├─PartitionUnion(Build) root + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t6.b)) + │ │ └─TableFullScan cop[tikv] table:t6, partition:p0 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t6.b)) + │ │ └─TableFullScan cop[tikv] table:t6, partition:p1 keep order:false, stats:pseudo + │ └─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t6.b)) + │ └─TableFullScan cop[tikv] table:t6, partition:p2 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t5.a)] ├─PartitionUnion(Build) root │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) - │ │ └─TableFullScan cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) + │ │ └─TableFullScan cop[tikv] table:t5, partition:p0 keep order:false, stats:pseudo │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) - │ │ └─TableFullScan cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) + │ │ └─TableFullScan cop[tikv] table:t5, partition:p1 keep order:false, stats:pseudo │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) - │ │ └─TableFullScan cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) + │ │ └─TableFullScan cop[tikv] table:t5, partition:p2 keep order:false, stats:pseudo │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) - │ │ └─TableFullScan cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) + │ │ └─TableFullScan cop[tikv] table:t5, partition:p3 keep order:false, stats:pseudo │ └─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) - │ └─TableFullScan cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo - └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t6.b, planner__core__casetest__rule__rule_join_reorder.t5.b)] + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) + │ └─TableFullScan cop[tikv] table:t5, partition:p4 keep order:false, stats:pseudo + └─HashJoin(Probe) root left outer join, left side:PartitionUnion, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.b)] ├─PartitionUnion(Build) root │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t6.b)) - │ │ └─TableFullScan cop[tikv] table:t6, partition:p0 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) + │ │ └─TableFullScan cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) + │ │ └─TableFullScan cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) + │ │ └─TableFullScan cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t6.b)) - │ │ └─TableFullScan cop[tikv] table:t6, partition:p1 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) + │ │ └─TableFullScan cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo │ └─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t6.b)) - │ └─TableFullScan cop[tikv] table:t6, partition:p2 keep order:false, stats:pseudo - └─PartitionUnion(Probe) root - ├─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) - │ └─TableFullScan cop[tikv] table:t5, partition:p0 keep order:false, stats:pseudo - ├─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) - │ └─TableFullScan cop[tikv] table:t5, partition:p1 keep order:false, stats:pseudo - ├─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) - │ └─TableFullScan cop[tikv] table:t5, partition:p2 keep order:false, stats:pseudo - ├─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) - │ └─TableFullScan cop[tikv] table:t5, partition:p3 keep order:false, stats:pseudo - └─TableReader root data:Selection - └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) - └─TableFullScan cop[tikv] table:t5, partition:p4 keep order:false, stats:pseudo + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) + │ └─TableFullScan cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.b)] + ├─PartitionUnion(Build) root + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) + │ │ └─TableFullScan cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) + │ │ └─TableFullScan cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) + │ │ └─TableFullScan cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo + │ └─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) + │ └─TableFullScan cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] + ├─PartitionUnion(Build) root + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ │ └─TableFullScan cop[tikv] table:t3, partition:p0 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ │ └─TableFullScan cop[tikv] table:t3, partition:p1 keep order:false, stats:pseudo + │ └─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ └─TableFullScan cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo + └─PartitionUnion(Probe) root + ├─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ └─TableFullScan cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo + ├─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ └─TableFullScan cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo + ├─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ └─TableFullScan cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo + └─TableReader root data:Selection + └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + └─TableFullScan cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo Level Code Message Warning 1815 We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid explain format='plan_tree' select /*+ leading(t5, t6, t3, t4) */ * from t2 left join (t1 join t3 on t1.a=t3.a join t4 on t3.b = t4.b) on t2.b=t1.b join t5 on t2.a = t5.a join t6 on t5.b=t6.b; id task access object operator info Projection root planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b, planner__core__casetest__rule__rule_join_reorder.t5.a, planner__core__casetest__rule__rule_join_reorder.t5.b, planner__core__casetest__rule__rule_join_reorder.t6.a, planner__core__casetest__rule__rule_join_reorder.t6.b -└─HashJoin root left outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.b)] - ├─Projection(Build) root planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b - │ └─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.b)] - │ ├─PartitionUnion(Build) root - │ │ ├─TableReader root data:Selection - │ │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) - │ │ │ └─TableFullScan cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo - │ │ ├─TableReader root data:Selection - │ │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) - │ │ │ └─TableFullScan cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo - │ │ ├─TableReader root data:Selection - │ │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) - │ │ │ └─TableFullScan cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo - │ │ └─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) - │ │ └─TableFullScan cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo - │ └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] - │ ├─PartitionUnion(Build) root - │ │ ├─TableReader root data:Selection - │ │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ │ │ └─TableFullScan cop[tikv] table:t3, partition:p0 keep order:false, stats:pseudo - │ │ ├─TableReader root data:Selection - │ │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ │ │ └─TableFullScan cop[tikv] table:t3, partition:p1 keep order:false, stats:pseudo - │ │ └─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ │ └─TableFullScan cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo - │ └─PartitionUnion(Probe) root - │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ │ └─TableFullScan cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo - │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ │ └─TableFullScan cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo - │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ │ └─TableFullScan cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo - │ └─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ └─TableFullScan cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo - └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t5.a, planner__core__casetest__rule__rule_join_reorder.t2.a)] +└─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t5.b, planner__core__casetest__rule__rule_join_reorder.t6.b)] + ├─PartitionUnion(Build) root + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t6.b)) + │ │ └─TableFullScan cop[tikv] table:t6, partition:p0 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t6.b)) + │ │ └─TableFullScan cop[tikv] table:t6, partition:p1 keep order:false, stats:pseudo + │ └─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t6.b)) + │ └─TableFullScan cop[tikv] table:t6, partition:p2 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t5.a)] ├─PartitionUnion(Build) root │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) - │ │ └─TableFullScan cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) + │ │ └─TableFullScan cop[tikv] table:t5, partition:p0 keep order:false, stats:pseudo │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) - │ │ └─TableFullScan cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) + │ │ └─TableFullScan cop[tikv] table:t5, partition:p1 keep order:false, stats:pseudo │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) - │ │ └─TableFullScan cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) + │ │ └─TableFullScan cop[tikv] table:t5, partition:p2 keep order:false, stats:pseudo │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) - │ │ └─TableFullScan cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) + │ │ └─TableFullScan cop[tikv] table:t5, partition:p3 keep order:false, stats:pseudo │ └─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) - │ └─TableFullScan cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo - └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t6.b, planner__core__casetest__rule__rule_join_reorder.t5.b)] + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) + │ └─TableFullScan cop[tikv] table:t5, partition:p4 keep order:false, stats:pseudo + └─HashJoin(Probe) root left outer join, left side:PartitionUnion, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.b)] ├─PartitionUnion(Build) root │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t6.b)) - │ │ └─TableFullScan cop[tikv] table:t6, partition:p0 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) + │ │ └─TableFullScan cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) + │ │ └─TableFullScan cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) + │ │ └─TableFullScan cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t6.b)) - │ │ └─TableFullScan cop[tikv] table:t6, partition:p1 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) + │ │ └─TableFullScan cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo │ └─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t6.b)) - │ └─TableFullScan cop[tikv] table:t6, partition:p2 keep order:false, stats:pseudo - └─PartitionUnion(Probe) root - ├─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) - │ └─TableFullScan cop[tikv] table:t5, partition:p0 keep order:false, stats:pseudo - ├─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) - │ └─TableFullScan cop[tikv] table:t5, partition:p1 keep order:false, stats:pseudo - ├─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) - │ └─TableFullScan cop[tikv] table:t5, partition:p2 keep order:false, stats:pseudo - ├─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) - │ └─TableFullScan cop[tikv] table:t5, partition:p3 keep order:false, stats:pseudo - └─TableReader root data:Selection - └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) - └─TableFullScan cop[tikv] table:t5, partition:p4 keep order:false, stats:pseudo -Level Code Message -Warning 1815 leading hint is inapplicable, check if the leading hint table is valid -Warning 1815 leading hint is inapplicable, check if the leading hint table is valid -explain format='plan_tree' select /*+ leading(t1, t2) */ * from t4 join t on t4.a=t.a right join t1 on t.a = t1.a join t2 on t1.b = t2.b join t3 on t2.b=t3.b; -id task access object operator info -Projection root planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b, planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b -└─HashJoin root right outer join, left side:Projection, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] - ├─Projection(Build) root planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b, planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b - │ └─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t4.a)] - │ ├─PartitionUnion(Build) root - │ │ ├─TableReader root data:Selection - │ │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) - │ │ │ └─TableFullScan cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo - │ │ ├─TableReader root data:Selection - │ │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) - │ │ │ └─TableFullScan cop[tikv] table:t, partition:p1 keep order:false, stats:pseudo - │ │ └─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) - │ │ └─TableFullScan cop[tikv] table:t, partition:p2 keep order:false, stats:pseudo - │ └─PartitionUnion(Probe) root - │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) - │ │ └─TableFullScan cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo - │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) - │ │ └─TableFullScan cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo - │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) - │ │ └─TableFullScan cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo - │ └─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) - │ └─TableFullScan cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo - └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.b)] - ├─PartitionUnion(Build) root + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) + │ └─TableFullScan cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.b)] + ├─PartitionUnion(Build) root + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) + │ │ └─TableFullScan cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) + │ │ └─TableFullScan cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) + │ │ └─TableFullScan cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo + │ └─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) + │ └─TableFullScan cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] + ├─PartitionUnion(Build) root + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ │ └─TableFullScan cop[tikv] table:t3, partition:p0 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ │ └─TableFullScan cop[tikv] table:t3, partition:p1 keep order:false, stats:pseudo + │ └─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ └─TableFullScan cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo + └─PartitionUnion(Probe) root + ├─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ └─TableFullScan cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo + ├─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ └─TableFullScan cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo + ├─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ └─TableFullScan cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo + └─TableReader root data:Selection + └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + └─TableFullScan cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo +Level Code Message +Warning 1815 leading hint is inapplicable, check if the leading hint table is valid +explain format='plan_tree' select /*+ leading(t1, t2) */ * from t4 join t on t4.a=t.a right join t1 on t.a = t1.a join t2 on t1.b = t2.b join t3 on t2.b=t3.b; +id task access object operator info +Projection root planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b, planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b +└─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] + ├─PartitionUnion(Build) root + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ │ └─TableFullScan cop[tikv] table:t3, partition:p0 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ │ └─TableFullScan cop[tikv] table:t3, partition:p1 keep order:false, stats:pseudo + │ └─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ └─TableFullScan cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] + ├─PartitionUnion(Build) root │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ │ └─TableFullScan cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) + │ │ └─TableFullScan cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ │ └─TableFullScan cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) + │ │ └─TableFullScan cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ │ └─TableFullScan cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) + │ │ └─TableFullScan cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) + │ │ └─TableFullScan cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo │ └─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ └─TableFullScan cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo - └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) + │ └─TableFullScan cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo + └─HashJoin(Probe) root right outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] ├─PartitionUnion(Build) root │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ │ └─TableFullScan cop[tikv] table:t3, partition:p0 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ │ └─TableFullScan cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ │ └─TableFullScan cop[tikv] table:t3, partition:p1 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ │ └─TableFullScan cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ │ └─TableFullScan cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo │ └─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ └─TableFullScan cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo - └─PartitionUnion(Probe) root - ├─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) - │ └─TableFullScan cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo - ├─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) - │ └─TableFullScan cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo - ├─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) - │ └─TableFullScan cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo - ├─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) - │ └─TableFullScan cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo - └─TableReader root data:Selection - └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) - └─TableFullScan cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ └─TableFullScan cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t4.a)] + ├─PartitionUnion(Build) root + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) + │ │ └─TableFullScan cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) + │ │ └─TableFullScan cop[tikv] table:t, partition:p1 keep order:false, stats:pseudo + │ └─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) + │ └─TableFullScan cop[tikv] table:t, partition:p2 keep order:false, stats:pseudo + └─PartitionUnion(Probe) root + ├─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) + │ └─TableFullScan cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo + ├─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) + │ └─TableFullScan cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo + ├─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) + │ └─TableFullScan cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo + └─TableReader root data:Selection + └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) + └─TableFullScan cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo Level Code Message Warning 1815 leading hint is inapplicable, check if the leading hint table is valid explain format='plan_tree' select /*+ leading(t2, t3) */ * from t4 join t on t4.a=t.a right join t1 on t.a = t1.a join t2 on t1.b = t2.b join t3 on t2.b=t3.b; id task access object operator info Projection root planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b, planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b -└─HashJoin root right outer join, left side:Projection, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] - ├─Projection(Build) root planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b, planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b - │ └─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t4.a)] - │ ├─PartitionUnion(Build) root - │ │ ├─TableReader root data:Selection - │ │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) - │ │ │ └─TableFullScan cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo - │ │ ├─TableReader root data:Selection - │ │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) - │ │ │ └─TableFullScan cop[tikv] table:t, partition:p1 keep order:false, stats:pseudo - │ │ └─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) - │ │ └─TableFullScan cop[tikv] table:t, partition:p2 keep order:false, stats:pseudo - │ └─PartitionUnion(Probe) root - │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) - │ │ └─TableFullScan cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo - │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) - │ │ └─TableFullScan cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo - │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) - │ │ └─TableFullScan cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo - │ └─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) - │ └─TableFullScan cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo - └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.b)] +└─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] + ├─PartitionUnion(Build) root + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ │ └─TableFullScan cop[tikv] table:t3, partition:p0 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ │ └─TableFullScan cop[tikv] table:t3, partition:p1 keep order:false, stats:pseudo + │ └─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ └─TableFullScan cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] ├─PartitionUnion(Build) root │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ │ └─TableFullScan cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) + │ │ └─TableFullScan cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) + │ │ └─TableFullScan cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ │ └─TableFullScan cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) + │ │ └─TableFullScan cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ │ └─TableFullScan cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) + │ │ └─TableFullScan cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo │ └─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ └─TableFullScan cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo - └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) + │ └─TableFullScan cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo + └─HashJoin(Probe) root right outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] ├─PartitionUnion(Build) root │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ │ └─TableFullScan cop[tikv] table:t3, partition:p0 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ │ └─TableFullScan cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ │ └─TableFullScan cop[tikv] table:t3, partition:p1 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ │ └─TableFullScan cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ │ └─TableFullScan cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo │ └─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ └─TableFullScan cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo - └─PartitionUnion(Probe) root - ├─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) - │ └─TableFullScan cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo - ├─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) - │ └─TableFullScan cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo - ├─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) - │ └─TableFullScan cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo - ├─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) - │ └─TableFullScan cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo - └─TableReader root data:Selection - └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) - └─TableFullScan cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ └─TableFullScan cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t4.a)] + ├─PartitionUnion(Build) root + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) + │ │ └─TableFullScan cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) + │ │ └─TableFullScan cop[tikv] table:t, partition:p1 keep order:false, stats:pseudo + │ └─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) + │ └─TableFullScan cop[tikv] table:t, partition:p2 keep order:false, stats:pseudo + └─PartitionUnion(Probe) root + ├─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) + │ └─TableFullScan cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo + ├─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) + │ └─TableFullScan cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo + ├─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) + │ └─TableFullScan cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo + └─TableReader root data:Selection + └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) + └─TableFullScan cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo Level Code Message Warning 1815 leading hint is inapplicable, check if the leading hint table is valid explain format='plan_tree' select /*+ leading(t1, t3) */ * from t4 join t on t4.a=t.a right join t1 on t.a = t1.a join t2 on t1.b = t2.b join t3 on t2.b=t3.b; id task access object operator info Projection root planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b, planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b -└─HashJoin root right outer join, left side:Projection, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] - ├─Projection(Build) root planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b, planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b - │ └─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t4.a)] - │ ├─PartitionUnion(Build) root - │ │ ├─TableReader root data:Selection - │ │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) - │ │ │ └─TableFullScan cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo - │ │ ├─TableReader root data:Selection - │ │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) - │ │ │ └─TableFullScan cop[tikv] table:t, partition:p1 keep order:false, stats:pseudo - │ │ └─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) - │ │ └─TableFullScan cop[tikv] table:t, partition:p2 keep order:false, stats:pseudo - │ └─PartitionUnion(Probe) root - │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) - │ │ └─TableFullScan cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo - │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) - │ │ └─TableFullScan cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo - │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) - │ │ └─TableFullScan cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo - │ └─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) - │ └─TableFullScan cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo - └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.b)] +└─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] + ├─PartitionUnion(Build) root + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ │ └─TableFullScan cop[tikv] table:t3, partition:p0 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ │ └─TableFullScan cop[tikv] table:t3, partition:p1 keep order:false, stats:pseudo + │ └─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ └─TableFullScan cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] ├─PartitionUnion(Build) root │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ │ └─TableFullScan cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) + │ │ └─TableFullScan cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) + │ │ └─TableFullScan cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ │ └─TableFullScan cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) + │ │ └─TableFullScan cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ │ └─TableFullScan cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) + │ │ └─TableFullScan cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo │ └─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ └─TableFullScan cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo - └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) + │ └─TableFullScan cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo + └─HashJoin(Probe) root right outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] ├─PartitionUnion(Build) root │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ │ └─TableFullScan cop[tikv] table:t3, partition:p0 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ │ └─TableFullScan cop[tikv] table:t1, partition:p0 keep order:false, stats:pseudo │ ├─TableReader root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ │ └─TableFullScan cop[tikv] table:t3, partition:p1 keep order:false, stats:pseudo + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ │ └─TableFullScan cop[tikv] table:t1, partition:p1 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ │ └─TableFullScan cop[tikv] table:t1, partition:p2 keep order:false, stats:pseudo │ └─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ └─TableFullScan cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo - └─PartitionUnion(Probe) root - ├─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) - │ └─TableFullScan cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo - ├─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) - │ └─TableFullScan cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo - ├─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) - │ └─TableFullScan cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo - ├─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) - │ └─TableFullScan cop[tikv] table:t2, partition:p3 keep order:false, stats:pseudo - └─TableReader root data:Selection - └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) - └─TableFullScan cop[tikv] table:t2, partition:p4 keep order:false, stats:pseudo + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ └─TableFullScan cop[tikv] table:t1, partition:p3 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t4.a)] + ├─PartitionUnion(Build) root + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) + │ │ └─TableFullScan cop[tikv] table:t, partition:p0 keep order:false, stats:pseudo + │ ├─TableReader root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) + │ │ └─TableFullScan cop[tikv] table:t, partition:p1 keep order:false, stats:pseudo + │ └─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) + │ └─TableFullScan cop[tikv] table:t, partition:p2 keep order:false, stats:pseudo + └─PartitionUnion(Probe) root + ├─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) + │ └─TableFullScan cop[tikv] table:t4, partition:p0 keep order:false, stats:pseudo + ├─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) + │ └─TableFullScan cop[tikv] table:t4, partition:p1 keep order:false, stats:pseudo + ├─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) + │ └─TableFullScan cop[tikv] table:t4, partition:p2 keep order:false, stats:pseudo + └─TableReader root data:Selection + └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) + └─TableFullScan cop[tikv] table:t4, partition:p3 keep order:false, stats:pseudo Level Code Message Warning 1815 leading hint is inapplicable, check if the leading hint table is valid explain format='plan_tree' select /*+ leading(t3) */ * from t2 right join (t1 left join t3 on t1.a=t3.a) on t2.b=t1.b; @@ -4324,11 +4309,11 @@ Level Code Message Warning 1815 leading hint is inapplicable, check if the leading hint table is valid explain format='plan_tree' select /*+ leading(t2) */ * from t1 join t2 on t1.a=t2.a right join t3 on t2.b=t3.b; id task access object operator info -HashJoin root right outer join, left side:Projection, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] -├─TableReader(Build) root data:TableFullScan -│ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo -└─Projection(Probe) root planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b - └─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] +Projection root planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b +└─HashJoin root right outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] + ├─TableReader(Build) root data:TableFullScan + │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] ├─TableReader(Build) root data:Selection │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) │ └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo @@ -4337,11 +4322,11 @@ HashJoin root right outer join, left side:Projection, equal:[eq(planner__core__ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo explain format='plan_tree' select /*+ leading(t3) */ * from t1 join t2 on t1.a=t2.a right join t3 on t2.b=t3.b; id task access object operator info -HashJoin root right outer join, left side:Projection, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] -├─TableReader(Build) root data:TableFullScan -│ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo -└─Projection(Probe) root planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b - └─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] +Projection root planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b +└─HashJoin root right outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] + ├─TableReader(Build) root data:TableFullScan + │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] ├─TableReader(Build) root data:Selection │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) │ └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo @@ -4350,11 +4335,11 @@ HashJoin root right outer join, left side:Projection, equal:[eq(planner__core__ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo explain format='plan_tree' select /*+ leading(t2, t3) */ * from t1 join t2 on t1.a=t2.a right join t3 on t2.b=t3.b; id task access object operator info -HashJoin root right outer join, left side:Projection, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] -├─TableReader(Build) root data:TableFullScan -│ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo -└─Projection(Probe) root planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b - └─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] +Projection root planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b +└─HashJoin root right outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] + ├─TableReader(Build) root data:TableFullScan + │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] ├─TableReader(Build) root data:Selection │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) │ └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo @@ -4363,14 +4348,13 @@ HashJoin root right outer join, left side:Projection, equal:[eq(planner__core__ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo Level Code Message Warning 1815 leading hint is inapplicable, check if the leading hint table is valid -Warning 1815 leading hint is inapplicable, check if the leading hint table is valid explain format='plan_tree' select /*+ leading(t3, t2) */ * from t1 join t2 on t1.a=t2.a right join t3 on t2.b=t3.b; id task access object operator info -HashJoin root right outer join, left side:Projection, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] -├─TableReader(Build) root data:TableFullScan -│ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo -└─Projection(Probe) root planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b - └─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] +Projection root planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b +└─HashJoin root right outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] + ├─TableReader(Build) root data:TableFullScan + │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] ├─TableReader(Build) root data:Selection │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) │ └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo @@ -4379,14 +4363,13 @@ HashJoin root right outer join, left side:Projection, equal:[eq(planner__core__ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo Level Code Message Warning 1815 leading hint is inapplicable, check if the leading hint table is valid -Warning 1815 leading hint is inapplicable, check if the leading hint table is valid explain format='plan_tree' select /*+ leading(t3, t1) */ * from t1 join t2 on t1.a=t2.a right join t3 on t2.b=t3.b; id task access object operator info -HashJoin root right outer join, left side:Projection, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] -├─TableReader(Build) root data:TableFullScan -│ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo -└─Projection(Probe) root planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b - └─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] +Projection root planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b +└─HashJoin root right outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] + ├─TableReader(Build) root data:TableFullScan + │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] ├─TableReader(Build) root data:Selection │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) │ └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo @@ -4395,7 +4378,6 @@ HashJoin root right outer join, left side:Projection, equal:[eq(planner__core__ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo Level Code Message Warning 1815 leading hint is inapplicable, check if the leading hint table is valid -Warning 1815 leading hint is inapplicable, check if the leading hint table is valid explain format='plan_tree' select /*+ leading(t2) */ * from t1 join t2 on t1.a=t2.a cross join t3; id task access object operator info Projection root planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b @@ -4422,8 +4404,6 @@ Projection root planner__core__casetest__rule__rule_join_reorder.t1.a, planner_ └─TableReader(Probe) root data:Selection └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)) └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo -Level Code Message -Warning 1815 leading hint is inapplicable, check if the leading hint table has join conditions with other tables explain format='plan_tree' select /*+ leading(t2, t3) */ * from t1 join t2 on t1.a=t2.a cross join t3; id task access object operator info Projection root planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b @@ -4474,8 +4454,6 @@ HashJoin root CARTESIAN inner join │ └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo └─TableReader(Probe) root data:TableFullScan └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo -Level Code Message -Warning 1815 leading hint is inapplicable, check if the leading hint table has join conditions with other tables explain format='plan_tree' select /*+ leading(t2, t1) */ * from t1 right join t2 on t1.a=t2.a cross join t3; id task access object operator info HashJoin root CARTESIAN inner join @@ -4487,8 +4465,6 @@ HashJoin root CARTESIAN inner join │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo └─TableReader(Probe) root data:TableFullScan └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo -Level Code Message -Warning 1815 leading hint is inapplicable, check if the leading hint table has join conditions with other tables explain format='plan_tree' select /*+ leading(t3, t1) */ * from t1 right join t2 on t1.a=t2.a right join t3 on t2.b=t3.b; id task access object operator info HashJoin root right outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] @@ -4503,7 +4479,6 @@ HashJoin root right outer join, left side:HashJoin, equal:[eq(planner__core__ca └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo Level Code Message Warning 1815 leading hint is inapplicable, check if the leading hint table is valid -Warning 1815 leading hint is inapplicable, check if the leading hint table is valid explain format='plan_tree' select /*+ leading(t1) */ * from t1 left join t2 on t1.a=t2.a straight_join t3; id task access object operator info HashJoin root CARTESIAN inner join @@ -6059,19 +6034,16 @@ HashJoin root left outer join, left side:TableReader, equal:[eq(planner__core__ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo explain format='plan_tree' select /*+ leading(t2, t1, t3) */ * from t2 left join (t1 left join t3 on t1.a=t3.a) on t2.b=t1.b; id task access object operator info -HashJoin root left outer join, left side:TableReader, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.b)] -├─TableReader(Build) root data:TableFullScan -│ └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo -└─HashJoin(Probe) root left outer join, left side:TableReader, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t3.a)] +HashJoin root left outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t3.a)] +├─TableReader(Build) root data:Selection +│ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)) +│ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo +└─HashJoin(Probe) root left outer join, left side:TableReader, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.b)] ├─TableReader(Build) root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)) - │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo - └─TableReader(Probe) root data:Selection - └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo -Level Code Message -Warning 1815 leading hint is inapplicable, check if the leading hint table is valid -Warning 1815 leading hint is inapplicable, check if the leading hint table is valid + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo + └─TableReader(Probe) root data:TableFullScan + └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo explain format='plan_tree' select /*+ leading(t2, t3) */ * from t2 left join (t1 join t3 on t1.a=t3.a join t4 on t3.b = t4.b) on t2.b=t1.b; id task access object operator info HashJoin root left outer join, left side:TableReader, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.b)] @@ -6090,14 +6062,13 @@ HashJoin root left outer join, left side:TableReader, equal:[eq(planner__core__ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo Level Code Message Warning 1815 leading hint is inapplicable, check if the leading hint table is valid -Warning 1815 leading hint is inapplicable, check if the leading hint table is valid explain format='plan_tree' select /*+ leading(t3, t4) */ * from t2 left join (t1 join t3 on t1.a=t3.a join t4 on t3.b = t4.b) on t2.b=t1.b; id task access object operator info -HashJoin root left outer join, left side:TableReader, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.b)] -├─TableReader(Build) root data:TableFullScan -│ └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo -└─Projection(Probe) root planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b - └─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] +Projection root planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b +└─HashJoin root left outer join, left side:TableReader, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.b)] + ├─TableReader(Build) root data:TableFullScan + │ └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] ├─TableReader(Build) root data:Selection │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo @@ -6111,87 +6082,83 @@ HashJoin root left outer join, left side:TableReader, equal:[eq(planner__core__ explain format='plan_tree' select /*+ leading(t3, t4) */ * from t2 left join (t1 join t3 on t1.a=t3.a join t4 on t3.b = t4.b) on t2.b=t1.b join t5 on t2.a = t5.a join t6 on t5.b=t6.b; id task access object operator info Projection root planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b, planner__core__casetest__rule__rule_join_reorder.t5.a, planner__core__casetest__rule__rule_join_reorder.t5.b, planner__core__casetest__rule__rule_join_reorder.t6.a, planner__core__casetest__rule__rule_join_reorder.t6.b -└─HashJoin root left outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.b)] - ├─Projection(Build) root planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b - │ └─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] - │ ├─TableReader(Build) root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo - │ └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.b)] - │ ├─TableReader(Build) root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo - │ └─TableReader(Probe) root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) - │ └─TableFullScan cop[tikv] table:t4 keep order:false, stats:pseudo - └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t5.b, planner__core__casetest__rule__rule_join_reorder.t6.b)] - ├─TableReader(Build) root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t6.b)) - │ └─TableFullScan cop[tikv] table:t6 keep order:false, stats:pseudo - └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t5.a, planner__core__casetest__rule__rule_join_reorder.t2.a)] - ├─TableReader(Build) root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) - │ └─TableFullScan cop[tikv] table:t5 keep order:false, stats:pseudo - └─TableReader(Probe) root data:Selection - └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) - └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo +└─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t5.b, planner__core__casetest__rule__rule_join_reorder.t6.b)] + ├─TableReader(Build) root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t6.b)) + │ └─TableFullScan cop[tikv] table:t6 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t5.a)] + ├─TableReader(Build) root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) + │ └─TableFullScan cop[tikv] table:t5 keep order:false, stats:pseudo + └─HashJoin(Probe) root left outer join, left side:TableReader, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.b)] + ├─TableReader(Build) root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) + │ └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] + ├─TableReader(Build) root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.b)] + ├─TableReader(Build) root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo + └─TableReader(Probe) root data:Selection + └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) + └─TableFullScan cop[tikv] table:t4 keep order:false, stats:pseudo explain format='plan_tree' select /*+ leading(t3, t4) leading(t5, t6) */ * from t2 left join (t1 join t3 on t1.a=t3.a join t4 on t3.b = t4.b) on t2.b=t1.b join t5 on t2.a = t5.a join t6 on t5.b=t6.b; id task access object operator info -Projection root planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b, planner__core__casetest__rule__rule_join_reorder.t5.a, planner__core__casetest__rule__rule_join_reorder.t5.b, planner__core__casetest__rule__rule_join_reorder.t6.a, planner__core__casetest__rule__rule_join_reorder.t6.b -└─HashJoin root left outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.b)] - ├─HashJoin(Build) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.b)] - │ ├─TableReader(Build) root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) - │ │ └─TableFullScan cop[tikv] table:t4 keep order:false, stats:pseudo - │ └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t3.a)] - │ ├─TableReader(Build) root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo - │ └─TableReader(Probe) root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo - └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t5.b, planner__core__casetest__rule__rule_join_reorder.t6.b)] +HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t5.b, planner__core__casetest__rule__rule_join_reorder.t6.b)] +├─TableReader(Build) root data:Selection +│ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t6.b)) +│ └─TableFullScan cop[tikv] table:t6 keep order:false, stats:pseudo +└─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t5.a)] + ├─TableReader(Build) root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) + │ └─TableFullScan cop[tikv] table:t5 keep order:false, stats:pseudo + └─HashJoin(Probe) root left outer join, left side:TableReader, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.b)] ├─TableReader(Build) root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t6.b)) - │ └─TableFullScan cop[tikv] table:t6 keep order:false, stats:pseudo - └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t5.a, planner__core__casetest__rule__rule_join_reorder.t2.a)] + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) + │ └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.b)] ├─TableReader(Build) root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) - │ └─TableFullScan cop[tikv] table:t5 keep order:false, stats:pseudo - └─TableReader(Probe) root data:Selection - └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) - └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) + │ └─TableFullScan cop[tikv] table:t4 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t3.a)] + ├─TableReader(Build) root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo + └─TableReader(Probe) root data:Selection + └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo Level Code Message Warning 1815 We can only use one leading hint at most, when multiple leading hints are used, all leading hints will be invalid explain format='plan_tree' select /*+ leading(t5, t6, t3, t4) */ * from t2 left join (t1 join t3 on t1.a=t3.a join t4 on t3.b = t4.b) on t2.b=t1.b join t5 on t2.a = t5.a join t6 on t5.b=t6.b; id task access object operator info -Projection root planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b, planner__core__casetest__rule__rule_join_reorder.t5.a, planner__core__casetest__rule__rule_join_reorder.t5.b, planner__core__casetest__rule__rule_join_reorder.t6.a, planner__core__casetest__rule__rule_join_reorder.t6.b -└─HashJoin root left outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.b)] - ├─HashJoin(Build) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.b)] - │ ├─TableReader(Build) root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) - │ │ └─TableFullScan cop[tikv] table:t4 keep order:false, stats:pseudo - │ └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t3.a)] - │ ├─TableReader(Build) root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo - │ └─TableReader(Probe) root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo - └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t5.b, planner__core__casetest__rule__rule_join_reorder.t6.b)] +HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t5.b, planner__core__casetest__rule__rule_join_reorder.t6.b)] +├─TableReader(Build) root data:Selection +│ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t6.b)) +│ └─TableFullScan cop[tikv] table:t6 keep order:false, stats:pseudo +└─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t5.a)] + ├─TableReader(Build) root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) + │ └─TableFullScan cop[tikv] table:t5 keep order:false, stats:pseudo + └─HashJoin(Probe) root left outer join, left side:TableReader, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t1.b)] ├─TableReader(Build) root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t6.b)) - │ └─TableFullScan cop[tikv] table:t6 keep order:false, stats:pseudo - └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t5.a, planner__core__casetest__rule__rule_join_reorder.t2.a)] + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) + │ └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t4.b)] ├─TableReader(Build) root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t5.b)) - │ └─TableFullScan cop[tikv] table:t5 keep order:false, stats:pseudo - └─TableReader(Probe) root data:Selection - └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) - └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.b)) + │ └─TableFullScan cop[tikv] table:t4 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t3.a)] + ├─TableReader(Build) root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo + └─TableReader(Probe) root data:Selection + └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo Level Code Message Warning 1815 leading hint is inapplicable, check if the leading hint table is valid -Warning 1815 leading hint is inapplicable, check if the leading hint table is valid explain format='plan_tree' select /*+ leading(t1, t2) */ * from t4 join t on t4.a=t.a right join t1 on t.a = t1.a join t2 on t1.b = t2.b join t3 on t2.b=t3.b; id task access object operator info HashJoin root right outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] @@ -6237,25 +6204,25 @@ Projection root planner__core__casetest__rule__rule_join_reorder.t4.a, planner_ └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo explain format='plan_tree' select /*+ leading(t1, t3) */ * from t4 join t on t4.a=t.a right join t1 on t.a = t1.a join t2 on t1.b = t2.b join t3 on t2.b=t3.b; id task access object operator info -HashJoin root right outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] -├─HashJoin(Build) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t.a)] -│ ├─TableReader(Build) root data:Selection -│ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) -│ │ └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo -│ └─TableReader(Probe) root data:Selection -│ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) -│ └─TableFullScan cop[tikv] table:t4 keep order:false, stats:pseudo -└─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] +HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] +├─TableReader(Build) root data:Selection +│ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) +│ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo +└─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] ├─TableReader(Build) root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo - └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) + │ └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo + └─HashJoin(Probe) root right outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] ├─TableReader(Build) root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) - │ └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo - └─TableReader(Probe) root data:Selection - └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t.a)] + ├─TableReader(Build) root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) + │ └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo + └─TableReader(Probe) root data:Selection + └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t4.a)) + └─TableFullScan cop[tikv] table:t4 keep order:false, stats:pseudo Level Code Message Warning 1815 leading hint is inapplicable, check if the leading hint table is valid explain format='plan_tree' select /*+ leading(t3) */ * from t2 right join (t1 left join t3 on t1.a=t3.a) on t2.b=t1.b; @@ -6402,58 +6369,58 @@ Projection root planner__core__casetest__rule__rule_join_reorder.t2.a, planner_ └─TableFullScan cop[tikv] table:t4 keep order:false, stats:pseudo explain format='plan_tree' select /*+ leading(t2) hash_join(t2) */ * from t left join t1 on t.a = t1.a right join t2 on t1.b = t2.b join t3 on t2.b = t3.b ; id task access object operator info -HashJoin root right outer join, left side:Projection, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] -├─Projection(Build) root planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b -│ └─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t.a)] -│ ├─TableReader(Build) root data:Selection -│ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) -│ │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo -│ └─TableReader(Probe) root data:Selection -│ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) -│ └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo -└─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] - ├─TableReader(Build) root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo - └─TableReader(Probe) root data:Selection - └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) - └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo +Projection root planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b +└─HashJoin root right outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] + ├─HashJoin(Build) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t.a)] + │ ├─TableReader(Build) root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo + │ └─TableReader(Probe) root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) + │ └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] + ├─TableReader(Build) root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo + └─TableReader(Probe) root data:Selection + └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) + └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo explain format='plan_tree' select /*+ leading(t2) hash_join(t1) */ * from t left join t1 on t.a = t1.a right join t2 on t1.b = t2.b join t3 on t2.b = t3.b ; id task access object operator info -HashJoin root right outer join, left side:Projection, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] -├─Projection(Build) root planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b -│ └─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t.a)] -│ ├─TableReader(Build) root data:Selection -│ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) -│ │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo -│ └─TableReader(Probe) root data:Selection -│ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) -│ └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo -└─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] - ├─TableReader(Build) root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo - └─TableReader(Probe) root data:Selection - └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) - └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo +Projection root planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b +└─HashJoin root right outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] + ├─HashJoin(Build) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t.a)] + │ ├─TableReader(Build) root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo + │ └─TableReader(Probe) root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) + │ └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] + ├─TableReader(Build) root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo + └─TableReader(Probe) root data:Selection + └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) + └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo explain format='plan_tree' select /*+ leading(t2) hash_join(t3) */ * from t left join t1 on t.a = t1.a right join t2 on t1.b = t2.b join t3 on t2.b = t3.b ; id task access object operator info -HashJoin root right outer join, left side:Projection, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] -├─Projection(Build) root planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b -│ └─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t.a)] -│ ├─TableReader(Build) root data:Selection -│ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) -│ │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo -│ └─TableReader(Probe) root data:Selection -│ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) -│ └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo -└─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] - ├─TableReader(Build) root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo - └─TableReader(Probe) root data:Selection - └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) - └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo +Projection root planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b +└─HashJoin root right outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] + ├─HashJoin(Build) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t.a)] + │ ├─TableReader(Build) root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo + │ └─TableReader(Probe) root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) + │ └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] + ├─TableReader(Build) root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo + └─TableReader(Probe) root data:Selection + └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) + └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo explain format='plan_tree' select /*+ leading(t) hash_join(t2) */ * from t left join t1 on t.a = t1.a left join t2 on t1.b = t2.b join t3 on t2.b = t3.b ; id task access object operator info HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] @@ -6507,58 +6474,57 @@ HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_re └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo explain format='plan_tree' select /*+ leading(t2) INL_JOIN(t1) */ * from t left join t1 on t.a = t1.a right join t2 on t1.b = t2.b join t3 on t2.b = t3.b ; id task access object operator info -HashJoin root right outer join, left side:Projection, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] -├─Projection(Build) root planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b -│ └─IndexJoin root inner join, inner:IndexLookUp, outer key:planner__core__casetest__rule__rule_join_reorder.t.a, inner key:planner__core__casetest__rule__rule_join_reorder.t1.a, equal cond:eq(planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t1.a) -│ ├─TableReader(Build) root data:Selection -│ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) -│ │ └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo -│ └─IndexLookUp(Probe) root -│ ├─Selection(Build) cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)) -│ │ └─IndexRangeScan cop[tikv] table:t1, index:a(a) range: decided by [eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t.a)], keep order:false, stats:pseudo -│ └─Selection(Probe) cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) -│ └─TableRowIDScan cop[tikv] table:t1 keep order:false, stats:pseudo -└─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] - ├─TableReader(Build) root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo - └─TableReader(Probe) root data:Selection - └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) - └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo +Projection root planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b +└─HashJoin root right outer join, left side:IndexJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] + ├─IndexJoin(Build) root inner join, inner:IndexLookUp, outer key:planner__core__casetest__rule__rule_join_reorder.t.a, inner key:planner__core__casetest__rule__rule_join_reorder.t1.a, equal cond:eq(planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t1.a) + │ ├─TableReader(Build) root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) + │ │ └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo + │ └─IndexLookUp(Probe) root + │ ├─Selection(Build) cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)) + │ │ └─IndexRangeScan cop[tikv] table:t1, index:a(a) range: decided by [eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t.a)], keep order:false, stats:pseudo + │ └─Selection(Probe) cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ └─TableRowIDScan cop[tikv] table:t1 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] + ├─TableReader(Build) root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo + └─TableReader(Probe) root data:Selection + └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) + └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo explain format='plan_tree' select /*+ leading(t2) INL_JOIN(t3) */ * from t left join t1 on t.a = t1.a right join t2 on t1.b = t2.b join t3 on t2.b = t3.b ; id task access object operator info -HashJoin root right outer join, left side:Projection, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] -├─Projection(Build) root planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b -│ └─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t.a)] -│ ├─TableReader(Build) root data:Selection -│ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) -│ │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo -│ └─TableReader(Probe) root data:Selection -│ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) -│ └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo -└─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] - ├─TableReader(Build) root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo - └─TableReader(Probe) root data:Selection - └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) - └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo +Projection root planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b +└─HashJoin root right outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] + ├─HashJoin(Build) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t.a)] + │ ├─TableReader(Build) root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo + │ └─TableReader(Probe) root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) + │ └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.b)] + ├─TableReader(Build) root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo + └─TableReader(Probe) root data:Selection + └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) + └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo Level Code Message Warning 1815 Optimizer Hint /*+ INL_JOIN(t3) */ or /*+ TIDB_INLJ(t3) */ is inapplicable explain format='plan_tree' select /*+ leading(t3) INL_JOIN(t1) */ * from t left join t1 on t.a = t1.a right join t2 on t1.b = t2.b join t3 on t2.b = t3.b ; id task access object operator info Projection root planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b -└─HashJoin root right outer join, left side:Projection, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] - ├─Projection(Build) root planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b - │ └─IndexJoin root inner join, inner:IndexLookUp, outer key:planner__core__casetest__rule__rule_join_reorder.t.a, inner key:planner__core__casetest__rule__rule_join_reorder.t1.a, equal cond:eq(planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t1.a) - │ ├─TableReader(Build) root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) - │ │ └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo - │ └─IndexLookUp(Probe) root - │ ├─Selection(Build) cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)) - │ │ └─IndexRangeScan cop[tikv] table:t1, index:a(a) range: decided by [eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t.a)], keep order:false, stats:pseudo - │ └─Selection(Probe) cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ └─TableRowIDScan cop[tikv] table:t1 keep order:false, stats:pseudo +└─HashJoin root right outer join, left side:IndexJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] + ├─IndexJoin(Build) root inner join, inner:IndexLookUp, outer key:planner__core__casetest__rule__rule_join_reorder.t.a, inner key:planner__core__casetest__rule__rule_join_reorder.t1.a, equal cond:eq(planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t1.a) + │ ├─TableReader(Build) root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) + │ │ └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo + │ └─IndexLookUp(Probe) root + │ ├─Selection(Build) cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)) + │ │ └─IndexRangeScan cop[tikv] table:t1, index:a(a) range: decided by [eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t.a)], keep order:false, stats:pseudo + │ └─Selection(Probe) cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ └─TableRowIDScan cop[tikv] table:t1 keep order:false, stats:pseudo └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] ├─TableReader(Build) root data:Selection │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) @@ -6569,15 +6535,14 @@ Projection root planner__core__casetest__rule__rule_join_reorder.t.a, planner__ explain format='plan_tree' select /*+ leading(t3) INL_JOIN(t3) */ * from t left join t1 on t.a = t1.a right join t2 on t1.b = t2.b join t3 on t2.b = t3.b ; id task access object operator info Projection root planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b -└─HashJoin root right outer join, left side:Projection, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] - ├─Projection(Build) root planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b - │ └─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t.a)] - │ ├─TableReader(Build) root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - │ │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo - │ └─TableReader(Probe) root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) - │ └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo +└─HashJoin root right outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] + ├─HashJoin(Build) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t.a)] + │ ├─TableReader(Build) root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo + │ └─TableReader(Probe) root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) + │ └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t3.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] ├─TableReader(Build) root data:Selection │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) @@ -6589,24 +6554,24 @@ Level Code Message Warning 1815 Optimizer Hint /*+ INL_JOIN(t3) */ or /*+ TIDB_INLJ(t3) */ is inapplicable explain format='plan_tree' select /*+ leading(t2) merge_join(t2) */ * from t left join t1 on t.a = t1.a right join t2 on t1.b = t2.b join t3 on t2.b = t3.b ; id task access object operator info -HashJoin root right outer join, left side:Projection, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] -├─Projection(Build) root planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b -│ └─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t.a)] -│ ├─TableReader(Build) root data:Selection -│ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) -│ │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo -│ └─TableReader(Probe) root data:Selection -│ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) -│ └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo -└─MergeJoin(Probe) root inner join, left key:planner__core__casetest__rule__rule_join_reorder.t2.b, right key:planner__core__casetest__rule__rule_join_reorder.t3.b - ├─Sort(Build) root planner__core__casetest__rule__rule_join_reorder.t3.b - │ └─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo - └─Sort(Probe) root planner__core__casetest__rule__rule_join_reorder.t2.b - └─TableReader root data:Selection - └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) - └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo +Projection root planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b +└─HashJoin root right outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] + ├─HashJoin(Build) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t.a)] + │ ├─TableReader(Build) root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo + │ └─TableReader(Probe) root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) + │ └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo + └─MergeJoin(Probe) root inner join, left key:planner__core__casetest__rule__rule_join_reorder.t2.b, right key:planner__core__casetest__rule__rule_join_reorder.t3.b + ├─Sort(Build) root planner__core__casetest__rule__rule_join_reorder.t3.b + │ └─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo + └─Sort(Probe) root planner__core__casetest__rule__rule_join_reorder.t2.b + └─TableReader root data:Selection + └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) + └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo explain format='plan_tree' select /*+ leading(t1) merge_join(t2) */ * from t join t1 on t.a = t1.a left join t2 on t1.b = t2.b join t3 on t2.b = t3.b ; id task access object operator info Projection root planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b @@ -6629,24 +6594,24 @@ Projection root planner__core__casetest__rule__rule_join_reorder.t.a, planner__ └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo explain format='plan_tree' select /*+ leading(t2) merge_join(t3) */ * from t left join t1 on t.a = t1.a right join t2 on t1.b = t2.b join t3 on t2.b = t3.b ; id task access object operator info -HashJoin root right outer join, left side:Projection, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] -├─Projection(Build) root planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b -│ └─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t.a)] -│ ├─TableReader(Build) root data:Selection -│ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) -│ │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo -│ └─TableReader(Probe) root data:Selection -│ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) -│ └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo -└─MergeJoin(Probe) root inner join, left key:planner__core__casetest__rule__rule_join_reorder.t2.b, right key:planner__core__casetest__rule__rule_join_reorder.t3.b - ├─Sort(Build) root planner__core__casetest__rule__rule_join_reorder.t3.b - │ └─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) - │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo - └─Sort(Probe) root planner__core__casetest__rule__rule_join_reorder.t2.b - └─TableReader root data:Selection - └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) - └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo +Projection root planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b +└─HashJoin root right outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.b)] + ├─HashJoin(Build) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t.a)] + │ ├─TableReader(Build) root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo + │ └─TableReader(Probe) root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t.a)) + │ └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo + └─MergeJoin(Probe) root inner join, left key:planner__core__casetest__rule__rule_join_reorder.t2.b, right key:planner__core__casetest__rule__rule_join_reorder.t3.b + ├─Sort(Build) root planner__core__casetest__rule__rule_join_reorder.t3.b + │ └─TableReader root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t3.b)) + │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo + └─Sort(Probe) root planner__core__casetest__rule__rule_join_reorder.t2.b + └─TableReader root data:Selection + └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) + └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo explain format='plan_tree' select /*+ leading(t3) merge_join(t3) */ * from t join t1 on t.a = t1.a join t2 on t1.b = t2.b join t3 on t2.b = t3.b ; id task access object operator info Projection root planner__core__casetest__rule__rule_join_reorder.t.a, planner__core__casetest__rule__rule_join_reorder.t.b, planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t3.a, planner__core__casetest__rule__rule_join_reorder.t3.b @@ -7226,19 +7191,20 @@ Projection root planner__core__casetest__rule__rule_join_reorder.t1.a, planner_ └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo explain format='plan_tree' select /*+ leading(t4) */ * from t1 left join t2 on t1.a=t2.a right join t4 on t1.b = t4.b where t1.a not in (select t3.a from t3); id task access object operator info -HashJoin root Null-aware anti semi join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t3.a)] +HashJoin root Null-aware anti semi join, left side:Projection, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t3.a)] ├─IndexReader(Build) root index:IndexFullScan │ └─IndexFullScan cop[tikv] table:t3, index:a(a) keep order:false, stats:pseudo -└─HashJoin(Probe) root right outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t4.b)] - ├─TableReader(Build) root data:TableFullScan - │ └─TableFullScan cop[tikv] table:t4 keep order:false, stats:pseudo - └─HashJoin(Probe) root left outer join, left side:TableReader, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t2.a)] +└─Projection(Probe) root planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b + └─HashJoin root left outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t2.a)] ├─TableReader(Build) root data:Selection │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)) │ └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo - └─TableReader(Probe) root data:Selection - └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) - └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo + └─HashJoin(Probe) root right outer join, left side:TableReader, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t4.b)] + ├─TableReader(Build) root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t1.b)) + │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo + └─TableReader(Probe) root data:TableFullScan + └─TableFullScan cop[tikv] table:t4 keep order:false, stats:pseudo explain format='plan_tree' select /*+ leading(t3@sel_2) */ * from t1 left join t2 on t1.a=t2.a where t1.a not in (select t3.a from t3); id task access object operator info HashJoin root Null-aware anti semi join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t3.a)] @@ -7366,11 +7332,11 @@ Level Code Message Warning 1815 There are no matching table names for (t4) in optimizer hint /*+ LEADING(t2, t4) */. Maybe you can use the table alias name explain format='plan_tree' select /*+ leading(t3) */ * from t1 join t2 on t1.a=t2.a right join (select * from t4) t3 on t2.b=t3.b; id task access object operator info -HashJoin root right outer join, left side:Projection, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t4.b)] -├─TableReader(Build) root data:TableFullScan -│ └─TableFullScan cop[tikv] table:t4 keep order:false, stats:pseudo -└─Projection(Probe) root planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b - └─HashJoin root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] +Projection root planner__core__casetest__rule__rule_join_reorder.t1.a, planner__core__casetest__rule__rule_join_reorder.t1.b, planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t4.a, planner__core__casetest__rule__rule_join_reorder.t4.b +└─HashJoin root right outer join, left side:HashJoin, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.b, planner__core__casetest__rule__rule_join_reorder.t4.b)] + ├─TableReader(Build) root data:TableFullScan + │ └─TableFullScan cop[tikv] table:t4 keep order:false, stats:pseudo + └─HashJoin(Probe) root inner join, equal:[eq(planner__core__casetest__rule__rule_join_reorder.t2.a, planner__core__casetest__rule__rule_join_reorder.t1.a)] ├─TableReader(Build) root data:Selection │ └─Selection cop[tikv] not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.a)), not(isnull(planner__core__casetest__rule__rule_join_reorder.t2.b)) │ └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo diff --git a/tests/integrationtest/r/planner/core/fulltext_search.result b/tests/integrationtest/r/planner/core/fulltext_search.result new file mode 100644 index 0000000000000..eb543c473e0e4 --- /dev/null +++ b/tests/integrationtest/r/planner/core/fulltext_search.result @@ -0,0 +1,240 @@ +set tidb_cost_model_version=1; +set @@tidb_opt_enable_alternative_logical_plans=ON; +drop table if exists articles; +create table articles (id int primary key, title varchar(200), body text); +insert into articles values +(1, 'MySQL Tutorial', 'This tutorial provides a basic MySQL tutorial'), +(2, 'How To Use MySQL Well', 'After you went through a MySQL tutorial'), +(3, 'Optimizing MySQL', 'In this tutorial we will show how to optimize MySQL'), +(4, 'MySQL vs. PostgreSQL', 'This article compares MySQL and PostgreSQL'), +(5, 'MySQL Security', 'How to secure your MySQL database'); +select id, title from articles where match(title) against('MySQL tutorial'); +id title +1 MySQL Tutorial +2 How To Use MySQL Well +3 Optimizing MySQL +4 MySQL vs. PostgreSQL +5 MySQL Security +select id, title from articles where match(title, body) against('MySQL tutorial'); +id title +1 MySQL Tutorial +2 How To Use MySQL Well +3 Optimizing MySQL +4 MySQL vs. PostgreSQL +5 MySQL Security +select id, title from articles where match(title) against('+MySQL +tutorial' in boolean mode); +id title +1 MySQL Tutorial +select id, title from articles where match(title) against('+MySQL -tutorial' in boolean mode); +id title +2 How To Use MySQL Well +3 Optimizing MySQL +4 MySQL vs. PostgreSQL +5 MySQL Security +select id, title from articles where match(title) against('Optim*' in boolean mode); +Error 1235 (42000): This version of TiDB doesn't yet support 'MATCH...AGAINST search term 'Optim*' is not supported in the LIKE fallback' +select id, title from articles where match(title, body) against('"MySQL tutorial"' in boolean mode); +Error 1235 (42000): This version of TiDB doesn't yet support 'MATCH...AGAINST search term '"MySQL' is not supported in the LIKE fallback' +select id, title from articles where match(title, body) against('+MySQL +database -PostgreSQL' in boolean mode); +id title +5 MySQL Security +select id, title from articles where match(title) against('tutorial security' in boolean mode); +id title +1 MySQL Tutorial +5 MySQL Security +select id, title from articles where match(title) against(''); +id title +set @@tidb_opt_enable_alternative_logical_plans=OFF; +select id, title from articles where match(title) against('MySQL'); +Error 1235 (42000): This version of TiDB doesn't yet support 'MATCH...AGAINST with this modifier on the native FTS path (modifier is not carried through pushdown to TiFlash)' +set @@tidb_opt_enable_alternative_logical_plans=ON; +select id, title from articles where match(title) against('MySQL'); +id title +1 MySQL Tutorial +2 How To Use MySQL Well +3 Optimizing MySQL +4 MySQL vs. PostgreSQL +5 MySQL Security +select id, title from articles where match(title) against('PostgreSQL'); +id title +4 MySQL vs. PostgreSQL +drop table if exists special_chars; +create table special_chars (id int primary key, content varchar(200)); +insert into special_chars values +(1, 'Progress is at 100%'), +(2, 'Progress is at 50%'), +(3, 'File name is test_file.txt'), +(4, 'Path is C:\\Windows\\System32'), +(5, 'Normal text without special chars'); +select id, content from special_chars where match(content) against('100%'); +Error 1235 (42000): This version of TiDB doesn't yet support 'MATCH...AGAINST search term '100%' is not supported in the LIKE fallback' +select id, content from special_chars where match(content) against('test_file'); +Error 1235 (42000): This version of TiDB doesn't yet support 'MATCH...AGAINST search term 'test_file' is not supported in the LIKE fallback' +select id, content from special_chars where match(content) against('C:\\Windows'); +Error 1235 (42000): This version of TiDB doesn't yet support 'MATCH...AGAINST search term 'C:\Windows' is not supported in the LIKE fallback' +select id, content from special_chars where match(content) against('+100% +Progress' in boolean mode); +Error 1235 (42000): This version of TiDB doesn't yet support 'MATCH...AGAINST search term '+100%' is not supported in the LIKE fallback' +drop table if exists special_chars; +select id, title from articles where match(title) against('-PostgreSQL -Security' in boolean mode); +id title +select id, title from articles where match(title) against('"MySQL tutorial' in boolean mode); +Error 1235 (42000): This version of TiDB doesn't yet support 'MATCH...AGAINST search term '"MySQL' is not supported in the LIKE fallback' +select id, title from articles where match(title) against('+MySQL +tutorial +-Security' in boolean mode); +id title +1 MySQL Tutorial +select id, title from articles where match(title) against('+MySQL +* tutorial' in boolean mode); +Error 1235 (42000): This version of TiDB doesn't yet support 'MATCH...AGAINST search term '+*' is not supported in the LIKE fallback' +select id, title from articles where match(title) against('+MySQL -PostgreSQL -Security -Well' in boolean mode); +id title +1 MySQL Tutorial +3 Optimizing MySQL +select id, title from articles where match(title) against('+MySQL -Security tutorial "How To" Optim*' in boolean mode); +Error 1235 (42000): This version of TiDB doesn't yet support 'MATCH...AGAINST search term '"How' is not supported in the LIKE fallback' +select id, title from articles where match(title) against(' +'); +id title +select id, title from articles where match(title) against('MySQL tutorial PostgreSQL'); +id title +1 MySQL Tutorial +2 How To Use MySQL Well +3 Optimizing MySQL +4 MySQL vs. PostgreSQL +5 MySQL Security +select id, title from articles where match(title) against('+"MySQL Tutorial"' in boolean mode); +Error 1235 (42000): This version of TiDB doesn't yet support 'MATCH...AGAINST search term '+"MySQL' is not supported in the LIKE fallback' +select id, title from articles where match(title) against('-"MySQL Tutorial"' in boolean mode); +Error 1235 (42000): This version of TiDB doesn't yet support 'MATCH...AGAINST search term '-"MySQL' is not supported in the LIKE fallback' +select id, title from articles where match(title) against('+MySQL +"How To" -PostgreSQL' in boolean mode); +Error 1235 (42000): This version of TiDB doesn't yet support 'MATCH...AGAINST search term '+"How' is not supported in the LIKE fallback' +select id, title from articles where match(title) against('tutorial -Security' in boolean mode); +id title +1 MySQL Tutorial +select id, title from articles where match(title) against('tutorial PostgreSQL -Security' in boolean mode); +id title +1 MySQL Tutorial +4 MySQL vs. PostgreSQL +select id, title from articles where match(title) against('MySQL, PostgreSQL.'); +Error 1235 (42000): This version of TiDB doesn't yet support 'MATCH...AGAINST search term 'MySQL,' is not supported in the LIKE fallback' +select id, title from articles where match(title) against('>MySQL MySQL' is not supported in the LIKE fallback' +select id, title from articles where match(title) against(NULL); +id title +select id, title from articles where not match(title) against(NULL); +id title +select id, title from articles where (match(title) against(NULL)); +id title +select id, title from articles where match(title) against('~Security ~PostgreSQL' in boolean mode); +Error 1235 (42000): This version of TiDB doesn't yet support 'MATCH...AGAINST search term '~Security' is not supported in the LIKE fallback' +select id, title from articles where match(title) against('MySQL' with query expansion); +Error 1235 (42000): This version of TiDB doesn't yet support 'MATCH...AGAINST WITH QUERY EXPANSION is not supported in the LIKE fallback' +select id, match(title) against('MySQL') as score from articles; +Error 1235 (42000): This version of TiDB doesn't yet support 'MATCH...AGAINST with this modifier on the native FTS path (modifier is not carried through pushdown to TiFlash)' +select id, title from articles order by match(title) against('MySQL') desc; +Error 1235 (42000): This version of TiDB doesn't yet support 'MATCH...AGAINST with this modifier on the native FTS path (modifier is not carried through pushdown to TiFlash)' +select id, title from articles group by id, title having match(title) against('PostgreSQL'); +id title +4 MySQL vs. PostgreSQL +select a.id, a.title from articles a inner join articles a2 on a.id = a2.id and match(a.title) against('Security'); +id title +5 MySQL Security +select id from articles where match(id) against('MySQL'); +Error 1235 (42000): This version of TiDB doesn't yet support 'Doesn't support match search on a non-string column without fulltext index' +select id from articles where match(id) against('xx-yy'); +Error 1235 (42000): This version of TiDB doesn't yet support 'Doesn't support match search on a non-string column without fulltext index' +select id from articles where match(id) against(NULL); +Error 1235 (42000): This version of TiDB doesn't yet support 'Doesn't support match search on a non-string column without fulltext index' +select id, title from articles +where match(title) against('MySQL') and match(body) against('PostgreSQL'); +id title +4 MySQL vs. PostgreSQL +select id, title from articles where not match(title) against('MySQL'); +id title +select id, title from articles where (match(title) against('MySQL')); +id title +1 MySQL Tutorial +2 How To Use MySQL Well +3 Optimizing MySQL +4 MySQL vs. PostgreSQL +5 MySQL Security +select id, title from articles where (match(title) against('MySQL')) is null; +Error 1235 (42000): This version of TiDB doesn't yet support 'MATCH...AGAINST with this modifier on the native FTS path (modifier is not carried through pushdown to TiFlash)' +select id, title from articles where (match(title) against('MySQL')) > 0.5; +Error 1235 (42000): This version of TiDB doesn't yet support 'MATCH...AGAINST with this modifier on the native FTS path (modifier is not carried through pushdown to TiFlash)' +select id, title from articles where (match(title) against('MySQL')) = 0; +Error 1235 (42000): This version of TiDB doesn't yet support 'MATCH...AGAINST with this modifier on the native FTS path (modifier is not carried through pushdown to TiFlash)' +select id, title from articles where (case when match(title) against('MySQL') then 1 else 0 end) = 1; +Error 1235 (42000): This version of TiDB doesn't yet support 'MATCH...AGAINST with this modifier on the native FTS path (modifier is not carried through pushdown to TiFlash)' +set @@tidb_enable_prepared_plan_cache=1; +prepare st_fts_lit from 'select id, title from articles where match(title) against(''MySQL'')'; +execute st_fts_lit; +id title +1 MySQL Tutorial +2 How To Use MySQL Well +3 Optimizing MySQL +4 MySQL vs. PostgreSQL +5 MySQL Security +execute st_fts_lit; +id title +1 MySQL Tutorial +2 How To Use MySQL Well +3 Optimizing MySQL +4 MySQL vs. PostgreSQL +5 MySQL Security +select @@last_plan_from_cache; +@@last_plan_from_cache +1 +deallocate prepare st_fts_lit; +set @@tidb_enable_prepared_plan_cache=DEFAULT; +set @@tidb_enable_prepared_plan_cache=1; +prepare st_fts from 'select id, title from articles where match(title) against(?)'; +set @q='MySQL'; +execute st_fts using @q; +id title +1 MySQL Tutorial +2 How To Use MySQL Well +3 Optimizing MySQL +4 MySQL vs. PostgreSQL +5 MySQL Security +execute st_fts using @q; +id title +1 MySQL Tutorial +2 How To Use MySQL Well +3 Optimizing MySQL +4 MySQL vs. PostgreSQL +5 MySQL Security +select @@last_plan_from_cache; +@@last_plan_from_cache +0 +set @q='PostgreSQL'; +execute st_fts using @q; +id title +4 MySQL vs. PostgreSQL +deallocate prepare st_fts; +set @@tidb_enable_prepared_plan_cache=DEFAULT; +set @@tidb_enable_prepared_plan_cache=1; +prepare st_fts_null from 'select id, title from articles where match(title) against(?)'; +set @q = NULL; +execute st_fts_null using @q; +id title +set @q = 'PostgreSQL'; +execute st_fts_null using @q; +id title +4 MySQL vs. PostgreSQL +select @@last_plan_from_cache; +@@last_plan_from_cache +0 +deallocate prepare st_fts_null; +set @@tidb_enable_prepared_plan_cache=DEFAULT; +select id, match(title) against('+MySQL' in boolean mode) as score from articles; +Error 1105 (HY000): cannot use 'MATCH ... AGAINST' outside of fulltext index +select id, title from articles order by match(title) against('+MySQL' in boolean mode) desc; +Error 1105 (HY000): cannot use 'MATCH ... AGAINST' outside of fulltext index +select id, title from articles where (match(title) against('+MySQL' in boolean mode)) is null; +Error 1105 (HY000): Full text search can only be used with a matching fulltext index or you write it in a wrong way +set @@tidb_opt_enable_alternative_logical_plans=OFF; +select id, title from articles where match(title) against('+MySQL' in boolean mode); +Error 1105 (HY000): Full text search can only be used with a matching fulltext index or you write it in a wrong way +set @@tidb_opt_enable_alternative_logical_plans=ON; +set @@tidb_opt_enable_alternative_logical_plans=OFF; +drop table if exists articles; diff --git a/tests/integrationtest/r/planner/core/issuetest/planner_issue.result b/tests/integrationtest/r/planner/core/issuetest/planner_issue.result index d696655e5888b..b11e5ec89b31b 100644 --- a/tests/integrationtest/r/planner/core/issuetest/planner_issue.result +++ b/tests/integrationtest/r/planner/core/issuetest/planner_issue.result @@ -958,19 +958,19 @@ left join (select a, b, c, (row_number() over (partition by b order by e asc)) from t4) tmp4 on tmp4.b = t2.c and tmp4.c = t3.c join t5 on t5.a = t1.e; id task access object operator info -HashJoin root inner join, equal:[eq(test.t5.a, test.t1.e)] -├─TableReader(Build) root data:Selection -│ └─Selection cop[tikv] not(isnull(test.t5.a)) -│ └─TableFullScan cop[tikv] table:t5 keep order:false, stats:pseudo -└─HashJoin(Probe) root left outer join, left side:HashJoin, equal:[eq(test.t2.c, test.t4.b) eq(test.t3.c, test.t4.c)] - ├─Selection(Build) root not(isnull(test.t4.c)) - │ └─Shuffle root execution info: concurrency:100, data sources:[TableReader] - │ └─Window root row_number()->Column#30 over(partition by test.t4.b order by test.t4.e rows between current row and current row) - │ └─Sort root test.t4.b, test.t4.e - │ └─ShuffleReceiver root - │ └─TableReader root data:Selection - │ └─Selection cop[tikv] not(isnull(test.t4.b)) - │ └─TableFullScan cop[tikv] table:t4 keep order:false, stats:pseudo +HashJoin root left outer join, left side:HashJoin, equal:[eq(test.t2.c, test.t4.b) eq(test.t3.c, test.t4.c)] +├─Selection(Build) root not(isnull(test.t4.c)) +│ └─Shuffle root execution info: concurrency:100, data sources:[TableReader] +│ └─Window root row_number()->Column#30 over(partition by test.t4.b order by test.t4.e rows between current row and current row) +│ └─Sort root test.t4.b, test.t4.e +│ └─ShuffleReceiver root +│ └─TableReader root data:Selection +│ └─Selection cop[tikv] not(isnull(test.t4.b)) +│ └─TableFullScan cop[tikv] table:t4 keep order:false, stats:pseudo +└─HashJoin(Probe) root inner join, equal:[eq(test.t1.e, test.t5.a)] + ├─TableReader(Build) root data:Selection + │ └─Selection cop[tikv] not(isnull(test.t5.a)) + │ └─TableFullScan cop[tikv] table:t5 keep order:false, stats:pseudo └─HashJoin(Probe) root inner join, equal:[eq(test.t1.b, test.t3.b)] ├─HashJoin(Build) root inner join, equal:[eq(test.t1.a, test.t2.b)] │ ├─TableReader(Build) root data:Selection diff --git a/tests/integrationtest/r/planner/core/join_reorder2.result b/tests/integrationtest/r/planner/core/join_reorder2.result index 74e5d15e28beb..fb94aca83af7d 100644 --- a/tests/integrationtest/r/planner/core/join_reorder2.result +++ b/tests/integrationtest/r/planner/core/join_reorder2.result @@ -57,15 +57,14 @@ Projection root planner__core__join_reorder2.t1.id, planner__core__join_reorder └─MergeJoin root inner join, left key:planner__core__join_reorder2.t1.id, right key:planner__core__join_reorder2.t2.id ├─TableReader(Build) root data:TableFullScan │ └─TableFullScan cop[tikv] table:t2 keep order:true, stats:pseudo - └─MergeJoin(Probe) root inner join, left key:planner__core__join_reorder2.t3.id, right key:planner__core__join_reorder2.t1.id + └─MergeJoin(Probe) root inner join, left key:planner__core__join_reorder2.t3.id, right key:planner__core__join_reorder2.t1.id, other cond:or(like(planner__core__join_reorder2.t3.name, "test3", 92), like(planner__core__join_reorder2.t4.name, "test4", 92)) ├─TableReader(Build) root data:TableFullScan │ └─TableFullScan cop[tikv] table:t1 keep order:true, stats:pseudo - └─Selection(Probe) root or(like(planner__core__join_reorder2.t3.name, "test3", 92), like(planner__core__join_reorder2.t4.name, "test4", 92)) - └─MergeJoin root left outer join, left side:TableReader, left key:planner__core__join_reorder2.t3.id, right key:planner__core__join_reorder2.t4.id - ├─TableReader(Build) root data:TableFullScan - │ └─TableFullScan cop[tikv] table:t4 keep order:true, stats:pseudo - └─TableReader(Probe) root data:TableFullScan - └─TableFullScan cop[tikv] table:t3 keep order:true, stats:pseudo + └─MergeJoin(Probe) root left outer join, left side:TableReader, left key:planner__core__join_reorder2.t3.id, right key:planner__core__join_reorder2.t4.id + ├─TableReader(Build) root data:TableFullScan + │ └─TableFullScan cop[tikv] table:t4 keep order:true, stats:pseudo + └─TableReader(Probe) root data:TableFullScan + └─TableFullScan cop[tikv] table:t3 keep order:true, stats:pseudo set @@tidb_opt_join_reorder_through_sel = 0; explain format = 'plan_tree' select /*+ leading(t1@sel_2, t4, t2@sel_2, t3@sel_2) */ * from (select t1.id, t1.name as n1, t2.name as n2, t3.name as n3 from t1 inner join t2 on t1.id=t2.id left join t3 on t2.id=t3.id where t2.name like 'test2' or t3.name like 'test3') sub diff --git a/tests/integrationtest/r/planner/core/plan_cache.result b/tests/integrationtest/r/planner/core/plan_cache.result index d38df4026c2c2..e685332891f88 100644 --- a/tests/integrationtest/r/planner/core/plan_cache.result +++ b/tests/integrationtest/r/planner/core/plan_cache.result @@ -686,11 +686,11 @@ TableReader_8 8000.00 root data:Selection_7 └─TableFullScan_6 10000.00 cop[tikv] table:t keep order:false, stats:pseudo explain format = 'plan_cache' select * from t t1, t t2; id estRows task access object operator info -HashJoin_21 100000000.00 root CARTESIAN inner join -├─TableReader_26(Build) 10000.00 root data:TableFullScan_25 -│ └─TableFullScan_25 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo -└─TableReader_24(Probe) 10000.00 root data:TableFullScan_23 - └─TableFullScan_23 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo +HashJoin_22 100000000.00 root CARTESIAN inner join +├─TableReader_27(Build) 10000.00 root data:TableFullScan_26 +│ └─TableFullScan_26 10000.00 cop[tikv] table:t2 keep order:false, stats:pseudo +└─TableReader_25(Probe) 10000.00 root data:TableFullScan_24 + └─TableFullScan_24 10000.00 cop[tikv] table:t1 keep order:false, stats:pseudo explain format = 'plan_cache' select * from t where a in (select a from t); id estRows task access object operator info HashJoin_27 9990.00 root inner join, equal:[eq(planner__core__plan_cache.t.a, planner__core__plan_cache.t.a)] diff --git a/tests/integrationtest/r/planner/core/rule_join_reorder.result b/tests/integrationtest/r/planner/core/rule_join_reorder.result index 0449eb337e635..99229b53b4a70 100644 --- a/tests/integrationtest/r/planner/core/rule_join_reorder.result +++ b/tests/integrationtest/r/planner/core/rule_join_reorder.result @@ -47,26 +47,26 @@ Sort root planner__core__rule_join_reorder.queries_identifier.id explain format = 'plan_tree' select * from t left join t1 on t.a=t1.a inner join t2 on t.a=t2.a and t2.c = 100 left join t3 on t2.a=t3.a and t3.b > 1 left join t4 on t2.a = t4.a where (t2.b > 100 or t.a > 10 or t1.b < 10); id task access object operator info Projection root planner__core__rule_join_reorder.t.a, planner__core__rule_join_reorder.t1.a, planner__core__rule_join_reorder.t1.b, planner__core__rule_join_reorder.t2.a, planner__core__rule_join_reorder.t2.b, planner__core__rule_join_reorder.t2.c, planner__core__rule_join_reorder.t3.a, planner__core__rule_join_reorder.t3.b, planner__core__rule_join_reorder.t4.a, planner__core__rule_join_reorder.t4.b -└─Selection root or(gt(planner__core__rule_join_reorder.t2.b, 100), or(gt(planner__core__rule_join_reorder.t.a, 10), lt(planner__core__rule_join_reorder.t1.b, 10))) - └─HashJoin root left outer join, left side:HashJoin, equal:[eq(planner__core__rule_join_reorder.t2.a, planner__core__rule_join_reorder.t4.a)] - ├─HashJoin(Build) root left outer join, left side:HashJoin, equal:[eq(planner__core__rule_join_reorder.t.a, planner__core__rule_join_reorder.t1.a)] - │ ├─HashJoin(Build) root inner join, equal:[eq(planner__core__rule_join_reorder.t2.a, planner__core__rule_join_reorder.t.a)] - │ │ ├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(planner__core__rule_join_reorder.t2.a, planner__core__rule_join_reorder.t3.a)] - │ │ │ ├─TableReader(Build) root data:Selection - │ │ │ │ └─Selection cop[tikv] eq(planner__core__rule_join_reorder.t2.c, 100), not(isnull(planner__core__rule_join_reorder.t2.a)) - │ │ │ │ └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo - │ │ │ └─TableReader(Probe) root data:Selection - │ │ │ └─Selection cop[tikv] gt(planner__core__rule_join_reorder.t3.b, 1), not(isnull(planner__core__rule_join_reorder.t3.a)) - │ │ │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo - │ │ └─TableReader(Probe) root data:Selection - │ │ └─Selection cop[tikv] not(isnull(planner__core__rule_join_reorder.t.a)) - │ │ └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo - │ └─TableReader(Probe) root data:Selection - │ └─Selection cop[tikv] not(isnull(planner__core__rule_join_reorder.t1.a)) - │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo - └─TableReader(Probe) root data:Selection - └─Selection cop[tikv] not(isnull(planner__core__rule_join_reorder.t4.a)) - └─TableFullScan cop[tikv] table:t4 keep order:false, stats:pseudo +└─HashJoin root left outer join, left side:Selection, equal:[eq(planner__core__rule_join_reorder.t2.a, planner__core__rule_join_reorder.t4.a)] + ├─Selection(Build) root or(gt(planner__core__rule_join_reorder.t2.b, 100), or(gt(planner__core__rule_join_reorder.t.a, 10), lt(planner__core__rule_join_reorder.t1.b, 10))) + │ └─HashJoin root left outer join, left side:HashJoin, equal:[eq(planner__core__rule_join_reorder.t.a, planner__core__rule_join_reorder.t1.a)] + │ ├─HashJoin(Build) root inner join, equal:[eq(planner__core__rule_join_reorder.t2.a, planner__core__rule_join_reorder.t.a)] + │ │ ├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(planner__core__rule_join_reorder.t2.a, planner__core__rule_join_reorder.t3.a)] + │ │ │ ├─TableReader(Build) root data:Selection + │ │ │ │ └─Selection cop[tikv] eq(planner__core__rule_join_reorder.t2.c, 100), not(isnull(planner__core__rule_join_reorder.t2.a)) + │ │ │ │ └─TableFullScan cop[tikv] table:t2 keep order:false, stats:pseudo + │ │ │ └─TableReader(Probe) root data:Selection + │ │ │ └─Selection cop[tikv] gt(planner__core__rule_join_reorder.t3.b, 1), not(isnull(planner__core__rule_join_reorder.t3.a)) + │ │ │ └─TableFullScan cop[tikv] table:t3 keep order:false, stats:pseudo + │ │ └─TableReader(Probe) root data:Selection + │ │ └─Selection cop[tikv] not(isnull(planner__core__rule_join_reorder.t.a)) + │ │ └─TableFullScan cop[tikv] table:t keep order:false, stats:pseudo + │ └─TableReader(Probe) root data:Selection + │ └─Selection cop[tikv] not(isnull(planner__core__rule_join_reorder.t1.a)) + │ └─TableFullScan cop[tikv] table:t1 keep order:false, stats:pseudo + └─TableReader(Probe) root data:Selection + └─Selection cop[tikv] not(isnull(planner__core__rule_join_reorder.t4.a)) + └─TableFullScan cop[tikv] table:t4 keep order:false, stats:pseudo drop table if exists t1, t2, t3; CREATE TABLE `t1` (`data_status` tinyint(1) DEFAULT '0',`part` tinyint(255) unsigned DEFAULT NULL); CREATE TABLE `t2` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`routing_rule_switch` tinyint(1) DEFAULT '0',PRIMARY KEY (`id`)); diff --git a/tests/integrationtest/r/select.result b/tests/integrationtest/r/select.result index 20a557bd0dcb5..4f6ece5163c7d 100644 --- a/tests/integrationtest/r/select.result +++ b/tests/integrationtest/r/select.result @@ -579,17 +579,17 @@ HashJoin root CARTESIAN left outer join, left side:TableReader, left cond:[eq(s └─TableFullScan cop[tikv] table:t2 keep order:false explain format = 'plan_tree' select * from t2 left join (t1 left join t3 on t1.a=t3.a) on t2.a=t3.a; id task access object operator info -HashJoin root left outer join, left side:TableReader, equal:[eq(select.t2.a, select.t3.a)] -├─Projection(Build) root select.t1.a, select.t1.b, select.t3.a, select.t3.b -│ └─HashJoin root inner join, equal:[eq(select.t3.a, select.t1.a)] -│ ├─TableReader(Build) root data:Selection -│ │ └─Selection cop[tikv] not(isnull(select.t3.a)) -│ │ └─TableFullScan cop[tikv] table:t3 keep order:false -│ └─TableReader(Probe) root data:Selection -│ └─Selection cop[tikv] not(isnull(select.t1.a)) -│ └─TableFullScan cop[tikv] table:t1 keep order:false -└─TableReader(Probe) root data:TableFullScan - └─TableFullScan cop[tikv] table:t2 keep order:false +Projection root select.t2.a, select.t2.b, select.t1.a, select.t1.b, select.t3.a, select.t3.b +└─HashJoin root left outer join, left side:TableReader, equal:[eq(select.t2.a, select.t3.a)] + ├─HashJoin(Build) root inner join, equal:[eq(select.t3.a, select.t1.a)] + │ ├─TableReader(Build) root data:Selection + │ │ └─Selection cop[tikv] not(isnull(select.t3.a)) + │ │ └─TableFullScan cop[tikv] table:t3 keep order:false + │ └─TableReader(Probe) root data:Selection + │ └─Selection cop[tikv] not(isnull(select.t1.a)) + │ └─TableFullScan cop[tikv] table:t1 keep order:false + └─TableReader(Probe) root data:TableFullScan + └─TableFullScan cop[tikv] table:t2 keep order:false explain format = 'plan_tree' select * from t2 left join t1 on t1.a=t2.a join t3 on t2.b=t3.b; id task access object operator info Projection root select.t2.a, select.t2.b, select.t1.a, select.t1.b, select.t3.a, select.t3.b @@ -620,65 +620,66 @@ Projection root select.t1.a, select.t1.b, select.t2.a, select.t2.b, select.t3.a └─TableFullScan cop[tikv] table:t1 keep order:false explain format = 'plan_tree' select * from t2 right join t3 on t3.a=t2.a right join t1 on t2.a=t1.a; id task access object operator info -HashJoin root right outer join, left side:Projection, equal:[eq(select.t2.a, select.t1.a)] -├─Projection(Build) root select.t2.a, select.t2.b, select.t3.a, select.t3.b -│ └─HashJoin root inner join, equal:[eq(select.t3.a, select.t2.a)] -│ ├─TableReader(Build) root data:Selection -│ │ └─Selection cop[tikv] not(isnull(select.t3.a)) -│ │ └─TableFullScan cop[tikv] table:t3 keep order:false -│ └─TableReader(Probe) root data:Selection -│ └─Selection cop[tikv] not(isnull(select.t2.a)) -│ └─TableFullScan cop[tikv] table:t2 keep order:false -└─TableReader(Probe) root data:TableFullScan - └─TableFullScan cop[tikv] table:t1 keep order:false +Projection root select.t2.a, select.t2.b, select.t3.a, select.t3.b, select.t1.a, select.t1.b +└─HashJoin root right outer join, left side:HashJoin, equal:[eq(select.t2.a, select.t1.a)] + ├─HashJoin(Build) root inner join, equal:[eq(select.t3.a, select.t2.a)] + │ ├─TableReader(Build) root data:Selection + │ │ └─Selection cop[tikv] not(isnull(select.t3.a)) + │ │ └─TableFullScan cop[tikv] table:t3 keep order:false + │ └─TableReader(Probe) root data:Selection + │ └─Selection cop[tikv] not(isnull(select.t2.a)) + │ └─TableFullScan cop[tikv] table:t2 keep order:false + └─TableReader(Probe) root data:TableFullScan + └─TableFullScan cop[tikv] table:t1 keep order:false explain format = 'plan_tree' select * from (t1 left join t2 on t1.a=t2.a) left join (t3 left join t4 on t3.a=t4.a) on t2.a=t4.a; id task access object operator info -HashJoin root left outer join, left side:HashJoin, equal:[eq(select.t2.a, select.t4.a)] -├─HashJoin(Build) root inner join, equal:[eq(select.t3.a, select.t4.a)] -│ ├─TableReader(Build) root data:Selection -│ │ └─Selection cop[tikv] not(isnull(select.t3.a)) -│ │ └─TableFullScan cop[tikv] table:t3 keep order:false +HashJoin root left outer join, left side:TableReader, equal:[eq(select.t1.a, select.t2.a)] +├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(select.t2.a, select.t4.a)] +│ ├─HashJoin(Build) root inner join, equal:[eq(select.t3.a, select.t4.a)] +│ │ ├─TableReader(Build) root data:Selection +│ │ │ └─Selection cop[tikv] not(isnull(select.t3.a)) +│ │ │ └─TableFullScan cop[tikv] table:t3 keep order:false +│ │ └─TableReader(Probe) root data:Selection +│ │ └─Selection cop[tikv] not(isnull(select.t4.a)) +│ │ └─TableFullScan cop[tikv] table:t4 keep order:false, stats:pseudo │ └─TableReader(Probe) root data:Selection -│ └─Selection cop[tikv] not(isnull(select.t4.a)) -│ └─TableFullScan cop[tikv] table:t4 keep order:false, stats:pseudo -└─HashJoin(Probe) root left outer join, left side:TableReader, equal:[eq(select.t1.a, select.t2.a)] - ├─TableReader(Build) root data:Selection - │ └─Selection cop[tikv] not(isnull(select.t2.a)) - │ └─TableFullScan cop[tikv] table:t2 keep order:false - └─TableReader(Probe) root data:TableFullScan - └─TableFullScan cop[tikv] table:t1 keep order:false +│ └─Selection cop[tikv] not(isnull(select.t2.a)) +│ └─TableFullScan cop[tikv] table:t2 keep order:false +└─TableReader(Probe) root data:TableFullScan + └─TableFullScan cop[tikv] table:t1 keep order:false explain format = 'plan_tree' select * from (t1 left join t2 on t1.a=t2.a) left join (t3 left join t4 on t3.a=t4.a) on t2.a=t3.a; id task access object operator info -HashJoin root left outer join, left side:HashJoin, equal:[eq(select.t2.a, select.t3.a)] -├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(select.t3.a, select.t4.a)] -│ ├─TableReader(Build) root data:Selection -│ │ └─Selection cop[tikv] not(isnull(select.t3.a)) -│ │ └─TableFullScan cop[tikv] table:t3 keep order:false -│ └─TableReader(Probe) root data:Selection -│ └─Selection cop[tikv] not(isnull(select.t4.a)) -│ └─TableFullScan cop[tikv] table:t4 keep order:false, stats:pseudo -└─HashJoin(Probe) root left outer join, left side:TableReader, equal:[eq(select.t1.a, select.t2.a)] - ├─TableReader(Build) root data:Selection - │ └─Selection cop[tikv] not(isnull(select.t2.a)) - │ └─TableFullScan cop[tikv] table:t2 keep order:false - └─TableReader(Probe) root data:TableFullScan - └─TableFullScan cop[tikv] table:t1 keep order:false +HashJoin root left outer join, left side:HashJoin, equal:[eq(select.t3.a, select.t4.a)] +├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(select.t1.a, select.t2.a)] +│ ├─HashJoin(Build) root left outer join, left side:TableReader, equal:[eq(select.t2.a, select.t3.a)] +│ │ ├─TableReader(Build) root data:Selection +│ │ │ └─Selection cop[tikv] not(isnull(select.t3.a)) +│ │ │ └─TableFullScan cop[tikv] table:t3 keep order:false +│ │ └─TableReader(Probe) root data:Selection +│ │ └─Selection cop[tikv] not(isnull(select.t2.a)) +│ │ └─TableFullScan cop[tikv] table:t2 keep order:false +│ └─TableReader(Probe) root data:TableFullScan +│ └─TableFullScan cop[tikv] table:t1 keep order:false +└─TableReader(Probe) root data:Selection + └─Selection cop[tikv] not(isnull(select.t4.a)) + └─TableFullScan cop[tikv] table:t4 keep order:false, stats:pseudo explain format = 'plan_tree' select * from (t1 left join t2 on t1.a=t2.a) left join (t3 left join t4 on t3.a=t4.a) on t1.a=t4.a; id task access object operator info -HashJoin root left outer join, left side:HashJoin, equal:[eq(select.t1.a, select.t4.a)] -├─HashJoin(Build) root inner join, equal:[eq(select.t3.a, select.t4.a)] -│ ├─TableReader(Build) root data:Selection -│ │ └─Selection cop[tikv] not(isnull(select.t3.a)) -│ │ └─TableFullScan cop[tikv] table:t3 keep order:false -│ └─TableReader(Probe) root data:Selection -│ └─Selection cop[tikv] not(isnull(select.t4.a)) -│ └─TableFullScan cop[tikv] table:t4 keep order:false, stats:pseudo -└─HashJoin(Probe) root left outer join, left side:TableReader, equal:[eq(select.t1.a, select.t2.a)] +Projection root select.t1.a, select.t1.b, select.t2.a, select.t2.b, select.t3.a, select.t3.b, select.t4.a, select.t4.b +└─HashJoin root left outer join, left side:HashJoin, equal:[eq(select.t1.a, select.t2.a)] ├─TableReader(Build) root data:Selection │ └─Selection cop[tikv] not(isnull(select.t2.a)) │ └─TableFullScan cop[tikv] table:t2 keep order:false - └─TableReader(Probe) root data:TableFullScan - └─TableFullScan cop[tikv] table:t1 keep order:false + └─HashJoin(Probe) root left outer join, left side:TableReader, equal:[eq(select.t1.a, select.t4.a)] + ├─HashJoin(Build) root inner join, equal:[eq(select.t3.a, select.t4.a)] + │ ├─TableReader(Build) root data:Selection + │ │ └─Selection cop[tikv] not(isnull(select.t3.a)) + │ │ └─TableFullScan cop[tikv] table:t3 keep order:false + │ └─TableReader(Probe) root data:Selection + │ └─Selection cop[tikv] not(isnull(select.t4.a)) + │ └─TableFullScan cop[tikv] table:t4 keep order:false, stats:pseudo + └─TableReader(Probe) root data:TableFullScan + └─TableFullScan cop[tikv] table:t1 keep order:false drop table if exists t3; create table t3(a char(10), primary key (a)); insert into t3 values ('a'); diff --git a/tests/integrationtest/r/sessionctx/setvar.result b/tests/integrationtest/r/sessionctx/setvar.result index b275f06243db3..c9efa0b64b39f 100644 --- a/tests/integrationtest/r/sessionctx/setvar.result +++ b/tests/integrationtest/r/sessionctx/setvar.result @@ -457,6 +457,26 @@ set @@tidb_enable_outer_join_reorder=default; select @@tidb_enable_outer_join_reorder; @@tidb_enable_outer_join_reorder 1 +select /*+ set_var(tidb_opt_enable_advanced_join_reorder=0) */ @@tidb_opt_enable_advanced_join_reorder; +@@tidb_opt_enable_advanced_join_reorder +0 +select @@tidb_opt_enable_advanced_join_reorder; +@@tidb_opt_enable_advanced_join_reorder +1 +set @@tidb_opt_enable_advanced_join_reorder=default; +select @@tidb_opt_enable_advanced_join_reorder; +@@tidb_opt_enable_advanced_join_reorder +1 +select /*+ set_var(tidb_opt_enable_advanced_join_reorder=1) */ @@tidb_opt_enable_advanced_join_reorder; +@@tidb_opt_enable_advanced_join_reorder +1 +select @@tidb_opt_enable_advanced_join_reorder; +@@tidb_opt_enable_advanced_join_reorder +1 +set @@tidb_opt_enable_advanced_join_reorder=default; +select @@tidb_opt_enable_advanced_join_reorder; +@@tidb_opt_enable_advanced_join_reorder +1 select /*+ set_var(tidb_enable_null_aware_anti_join=0) */ @@tidb_enable_null_aware_anti_join; @@tidb_enable_null_aware_anti_join 0 diff --git a/tests/integrationtest/t/planner/core/fulltext_search.test b/tests/integrationtest/t/planner/core/fulltext_search.test new file mode 100644 index 0000000000000..798fdb992d029 --- /dev/null +++ b/tests/integrationtest/t/planner/core/fulltext_search.test @@ -0,0 +1,322 @@ +# Test cases for MATCH...AGAINST to LIKE conversion via alternative logical plans + +# Setup +set tidb_cost_model_version=1; +set @@tidb_opt_enable_alternative_logical_plans=ON; +drop table if exists articles; +create table articles (id int primary key, title varchar(200), body text); +insert into articles values + (1, 'MySQL Tutorial', 'This tutorial provides a basic MySQL tutorial'), + (2, 'How To Use MySQL Well', 'After you went through a MySQL tutorial'), + (3, 'Optimizing MySQL', 'In this tutorial we will show how to optimize MySQL'), + (4, 'MySQL vs. PostgreSQL', 'This article compares MySQL and PostgreSQL'), + (5, 'MySQL Security', 'How to secure your MySQL database'); + +# Test 1: Natural Language Mode - Single Column +select id, title from articles where match(title) against('MySQL tutorial'); + +# Test 2: Natural Language Mode - Multiple Columns +select id, title from articles where match(title, body) against('MySQL tutorial'); + +# Test 3: Boolean Mode - Required Terms +select id, title from articles where match(title) against('+MySQL +tutorial' in boolean mode); + +# Test 4: Boolean Mode - Excluded Terms +select id, title from articles where match(title) against('+MySQL -tutorial' in boolean mode); + +# Test 5: Boolean Mode - Prefix Wildcard is rejected by the strict subset (LIKE +# cannot enforce word-start boundaries; MySQL FTS would only match words +# starting with the prefix). Falls back to native FTS path; without an FTS +# index, surfaces the rewrite error. +-- error 1235 +select id, title from articles where match(title) against('Optim*' in boolean mode); + +# Test 6: Boolean Mode - Exact Phrase is rejected by the strict subset (LIKE +# cannot enforce word boundaries inside a phrase). Falls back to native FTS +# path; without an FTS index, surfaces the rewrite error. +-- error 1235 +select id, title from articles where match(title, body) against('"MySQL tutorial"' in boolean mode); + +# Test 7: Boolean Mode - Complex Query +select id, title from articles where match(title, body) against('+MySQL +database -PostgreSQL' in boolean mode); + +# Test 8: Boolean Mode - Optional Terms +select id, title from articles where match(title) against('tutorial security' in boolean mode); + +# Test 9: Empty Search String +select id, title from articles where match(title) against(''); + +# Test 10: Test without alternative plans (native FTS path - errors without TiFlash) +set @@tidb_opt_enable_alternative_logical_plans=OFF; +-- error 1235 + +select id, title from articles where match(title) against('MySQL'); + +# Test 11: Switch back to alternative plans mode +set @@tidb_opt_enable_alternative_logical_plans=ON; +select id, title from articles where match(title) against('MySQL'); + +# Test 12: Natural Language Mode with single word +select id, title from articles where match(title) against('PostgreSQL'); + +# Test 13: Special characters in search strings are rejected by the strict +# subset (MySQL FTS treats %, _, \, : etc. as word separators or operators, +# so a substring LIKE on them would produce results inconsistent with MySQL +# FTS tokenization). Each rejection falls back to the native FTS path; without +# an FTS index, surfaces the rewrite error. +drop table if exists special_chars; +create table special_chars (id int primary key, content varchar(200)); +insert into special_chars values + (1, 'Progress is at 100%'), + (2, 'Progress is at 50%'), + (3, 'File name is test_file.txt'), + (4, 'Path is C:\\Windows\\System32'), + (5, 'Normal text without special chars'); + +-- error 1235 +select id, content from special_chars where match(content) against('100%'); + +-- error 1235 +select id, content from special_chars where match(content) against('test_file'); + +-- error 1235 +select id, content from special_chars where match(content) against('C:\\Windows'); + +-- error 1235 +select id, content from special_chars where match(content) against('+100% +Progress' in boolean mode); + +drop table if exists special_chars; + +# Test 14: Boolean mode - only excluded terms (no required/optional) +select id, title from articles where match(title) against('-PostgreSQL -Security' in boolean mode); + +# Test 15: Boolean mode - quote is rejected by the strict subset. +-- error 1235 +select id, title from articles where match(title) against('"MySQL tutorial' in boolean mode); + +# Test 16: Boolean mode - mixed whitespace (tabs and newlines) +select id, title from articles where match(title) against('+MySQL +tutorial +-Security' in boolean mode); + +# Test 17: Boolean mode - `*` is rejected by the strict subset. +-- error 1235 +select id, title from articles where match(title) against('+MySQL +* tutorial' in boolean mode); + +# Test 18: Boolean mode - multiple excluded terms +select id, title from articles where match(title) against('+MySQL -PostgreSQL -Security -Well' in boolean mode); + +# Test 19: Boolean mode - mixed `*` and quoted phrase are rejected. +-- error 1235 +select id, title from articles where match(title) against('+MySQL -Security tutorial "How To" Optim*' in boolean mode); + +# Test 20: Natural language mode - only whitespace +select id, title from articles where match(title) against(' + '); + +# Test 21: Natural language mode - multiple spaces between words +select id, title from articles where match(title) against('MySQL tutorial PostgreSQL'); + +# Test 22: Boolean mode - required phrase rejected by strict subset. +-- error 1235 +select id, title from articles where match(title) against('+"MySQL Tutorial"' in boolean mode); + +# Test 23: Boolean mode - excluded phrase rejected by strict subset. +-- error 1235 +select id, title from articles where match(title) against('-"MySQL Tutorial"' in boolean mode); + +# Test 24: Boolean mode - phrase mixed with words rejected by strict subset. +-- error 1235 +select id, title from articles where match(title) against('+MySQL +"How To" -PostgreSQL' in boolean mode); + +# Test 25: Boolean mode - optional + excluded (optional treated as required filter) +select id, title from articles where match(title) against('tutorial -Security' in boolean mode); + +# Test 26: Boolean mode - optional + excluded with multiple optionals +select id, title from articles where match(title) against('tutorial PostgreSQL -Security' in boolean mode); + +# Test 27: Natural language mode - punctuation in tokens rejected by strict +# subset. MySQL FTS would tokenize away the punctuation, but a substring LIKE +# would include it, so we refuse the rewrite. +-- error 1235 +select id, title from articles where match(title) against('MySQL, PostgreSQL.'); + +# Test 28: Boolean mode - relevance modifiers > < rejected by strict subset. +-- error 1235 +select id, title from articles where match(title) against('>MySQL 0.5; + +# Test 36g: Scalar-position MATCH — explicit comparison to 0. Native returns +# the score (≥0). Coincidentally a LIKE 0/1 result agrees on "no match" +# rows, but we still route to native to preserve relevance-score semantics +# uniformly across scalar positions. +-- error 1235 +select id, title from articles where (match(title) against('MySQL')) = 0; + +# Test 36h: Scalar-position MATCH inside CASE WHEN. The WHEN expression takes +# a boolean condition, but the MATCH is buried under the CASE node, which is +# a non-boolean ancestor. Falls through to native. +-- error 1235 +select id, title from articles where (case when match(title) against('MySQL') then 1 else 0 end) = 1; + +# Test 37: Plan cache - prepared statement with literal AGAINST IS cacheable. +# The LIKE rewrite bakes the search string into pattern constants; for a true +# literal those constants are stable across executions, so the plan must be +# cacheable. Verifies the LIKE fallback only skips plan cache when the AGAINST +# constant is mutable (param marker / deferred expr), not for plain literals. +set @@tidb_enable_prepared_plan_cache=1; +prepare st_fts_lit from 'select id, title from articles where match(title) against(''MySQL'')'; +execute st_fts_lit; +execute st_fts_lit; +select @@last_plan_from_cache; +deallocate prepare st_fts_lit; +set @@tidb_enable_prepared_plan_cache=DEFAULT; + +# Test 38: Plan cache - prepared statement with ? in AGAINST must NOT cache. +# A param marker is mutable across executions; baking the first execution's +# pattern would silently produce wrong results when the bind value changes. +set @@tidb_enable_prepared_plan_cache=1; +prepare st_fts from 'select id, title from articles where match(title) against(?)'; +set @q='MySQL'; +execute st_fts using @q; +execute st_fts using @q; +select @@last_plan_from_cache; +# Bind a different value to confirm results stay correct under the non-cached plan. +set @q='PostgreSQL'; +execute st_fts using @q; +deallocate prepare st_fts; +set @@tidb_enable_prepared_plan_cache=DEFAULT; + +# Test 38a: Prepared statement with a NULL first bind followed by a non-NULL +# bind. Pre-fix the LIKE fallback's NULL fast-path emitted Constant(0) and +# ran BEFORE the plan-cache skip check, so the prepared plan could cache a +# constant-false plan that a later non-NULL bind would silently reuse, +# returning zero rows instead of the matching ones. The fix moves the +# plan-cache skip ahead of the NULL fast-path (so mutable AGAINST always +# disables caching) and changes the NULL emission to Constant(NULL) (so +# NULL three-valued logic is preserved). After the fix, the second execute +# must return the PostgreSQL row, and @@last_plan_from_cache must be 0. +set @@tidb_enable_prepared_plan_cache=1; +prepare st_fts_null from 'select id, title from articles where match(title) against(?)'; +set @q = NULL; +execute st_fts_null using @q; +set @q = 'PostgreSQL'; +execute st_fts_null using @q; +select @@last_plan_from_cache; +deallocate prepare st_fts_null; +set @@tidb_enable_prepared_plan_cache=DEFAULT; + +# Note: user variables in AGAINST (e.g., AGAINST(@search)) are rejected at +# rewrite time as a non-constant search string, so they never reach the +# plan-cache decision and need no separate cache-skip coverage here. + +# Test 39: Non-default modifier in a scoring context (SELECT field). LIKE +# cannot produce a float relevance score so it can't rescue this; the modifier +# guard in matchAgainstToBuiltin must error at plan time rather than emit a +# native FTS expression that TiFlash would silently execute as natural-language +# mode (the tipb pushdown protocol drops the modifier). +-- error 1105 +select id, match(title) against('+MySQL' in boolean mode) as score from articles; + +# Test 40: Non-default modifier in ORDER BY (scoring context). Same guard. +-- error 1105 +select id, title from articles order by match(title) against('+MySQL' in boolean mode) desc; + +# Test 41: Non-default modifier in a scalar predicate position (IS NULL). +# Even with alternative logical plans enabled, the LIKE round only rewrites +# direct-boolean MATCHes; the scalar position falls through to native, which +# must reject the modifier rather than mistranslate it on TiFlash. +-- error 1105 +select id, title from articles where (match(title) against('+MySQL' in boolean mode)) is null; + +# Test 42: Boolean mode in WHERE with alternative logical plans disabled. +# Without the fts-like-fallback rescue, native is the final plan, so the +# modifier guard must fire. (Pre-PR this query would push to TiFlash and +# silently execute as natural-language mode.) +set @@tidb_opt_enable_alternative_logical_plans=OFF; +-- error 1105 +select id, title from articles where match(title) against('+MySQL' in boolean mode); +set @@tidb_opt_enable_alternative_logical_plans=ON; + +# Cleanup +set @@tidb_opt_enable_alternative_logical_plans=OFF; +drop table if exists articles; diff --git a/tests/integrationtest/t/sessionctx/setvar.test b/tests/integrationtest/t/sessionctx/setvar.test index d220bba452b11..26073a2acde7c 100644 --- a/tests/integrationtest/t/sessionctx/setvar.test +++ b/tests/integrationtest/t/sessionctx/setvar.test @@ -188,6 +188,14 @@ select /*+ set_var(tidb_enable_outer_join_reorder=1) */ @@tidb_enable_outer_join select @@tidb_enable_outer_join_reorder; set @@tidb_enable_outer_join_reorder=default; select @@tidb_enable_outer_join_reorder; +select /*+ set_var(tidb_opt_enable_advanced_join_reorder=0) */ @@tidb_opt_enable_advanced_join_reorder; +select @@tidb_opt_enable_advanced_join_reorder; +set @@tidb_opt_enable_advanced_join_reorder=default; +select @@tidb_opt_enable_advanced_join_reorder; +select /*+ set_var(tidb_opt_enable_advanced_join_reorder=1) */ @@tidb_opt_enable_advanced_join_reorder; +select @@tidb_opt_enable_advanced_join_reorder; +set @@tidb_opt_enable_advanced_join_reorder=default; +select @@tidb_opt_enable_advanced_join_reorder; select /*+ set_var(tidb_enable_null_aware_anti_join=0) */ @@tidb_enable_null_aware_anti_join; select @@tidb_enable_null_aware_anti_join; set @@tidb_enable_null_aware_anti_join=default;