diff --git a/planner/core/plan_cost_ver1.go b/planner/core/plan_cost_ver1.go index 0cd8c5eabd473..d1a7e6e95a9c5 100644 --- a/planner/core/plan_cost_ver1.go +++ b/planner/core/plan_cost_ver1.go @@ -852,7 +852,7 @@ func (p *PhysicalHashJoin) GetCost(lCnt, rCnt float64, isMPP bool, costFlag uint sessVars := p.ctx.GetSessionVars() oomUseTmpStorage := variable.EnableTmpStorageOnOOM.Load() memQuota := sessVars.MemTracker.GetBytesLimit() // sessVars.MemQuotaQuery && hint - rowSize := getAvgRowSize(build.statsInfo(), build.Schema()) + rowSize := getAvgRowSize(build.statsInfo(), build.Schema().Columns) spill := oomUseTmpStorage && memQuota > 0 && rowSize*buildCnt > float64(memQuota) && p.storeTp != kv.TiFlash // Cost of building hash table. cpuFactor := sessVars.GetCPUFactor() @@ -1049,7 +1049,7 @@ func (p *PhysicalSort) GetCost(count float64, schema *expression.Schema) float64 oomUseTmpStorage := variable.EnableTmpStorageOnOOM.Load() memQuota := sessVars.MemTracker.GetBytesLimit() // sessVars.MemQuotaQuery && hint - rowSize := getAvgRowSize(p.statsInfo(), schema) + rowSize := getAvgRowSize(p.statsInfo(), schema.Columns) spill := oomUseTmpStorage && memQuota > 0 && rowSize*count > float64(memQuota) diskCost := count * sessVars.GetDiskFactor() * rowSize if !spill { diff --git a/planner/core/plan_cost_ver2.go b/planner/core/plan_cost_ver2.go index 1afa6237386ae..b717b8580d2b5 100644 --- a/planner/core/plan_cost_ver2.go +++ b/planner/core/plan_cost_ver2.go @@ -115,7 +115,7 @@ func (p *PhysicalIndexScan) getPlanCostVer2(taskType property.TaskType, option * } rows := getCardinality(p, option.CostFlag) - rowSize := math.Max(p.getScanRowSize(), 2.0) + rowSize := math.Max(getAvgRowSize(p.stats, p.schema.Columns), 2.0) // consider all index columns scanFactor := getTaskScanFactorVer2(p, taskType) p.planCostVer2 = scanCostVer2(option, rows, rowSize, scanFactor) @@ -132,7 +132,13 @@ func (p *PhysicalTableScan) getPlanCostVer2(taskType property.TaskType, option * } rows := getCardinality(p, option.CostFlag) - rowSize := math.Max(p.getScanRowSize(), 2.0) + var rowSize float64 + if p.StoreType == kv.TiKV { + rowSize = getAvgRowSize(p.stats, p.tblCols) // consider all columns if TiKV + } else { // TiFlash + rowSize = getAvgRowSize(p.stats, p.schema.Columns) + } + rowSize = math.Max(rowSize, 2.0) scanFactor := getTaskScanFactorVer2(p, taskType) p.planCostVer2 = scanCostVer2(option, rows, rowSize, scanFactor) @@ -155,7 +161,7 @@ func (p *PhysicalIndexReader) getPlanCostVer2(taskType property.TaskType, option } rows := getCardinality(p.indexPlan, option.CostFlag) - rowSize := getAvgRowSize(p.indexPlan.Stats(), p.indexPlan.Schema()) + rowSize := getAvgRowSize(p.indexPlan.Stats(), p.indexPlan.Schema().Columns) netFactor := getTaskNetFactorVer2(p, taskType) concurrency := float64(p.ctx.GetSessionVars().DistSQLScanConcurrency()) @@ -180,7 +186,7 @@ func (p *PhysicalTableReader) getPlanCostVer2(taskType property.TaskType, option } rows := getCardinality(p.tablePlan, option.CostFlag) - rowSize := getAvgRowSize(p.tablePlan.Stats(), p.tablePlan.Schema()) + rowSize := getAvgRowSize(p.tablePlan.Stats(), p.tablePlan.Schema().Columns) netFactor := getTaskNetFactorVer2(p, taskType) concurrency := float64(p.ctx.GetSessionVars().DistSQLScanConcurrency()) childType := property.CopSingleReadTaskType @@ -284,7 +290,7 @@ func (p *PhysicalIndexMergeReader) getPlanCostVer2(taskType property.TaskType, o var tableSideCost costVer2 if tablePath := p.tablePlan; tablePath != nil { rows := getCardinality(tablePath, option.CostFlag) - rowSize := getAvgRowSize(tablePath.Stats(), tablePath.Schema()) + rowSize := getAvgRowSize(tablePath.Stats(), tablePath.Schema().Columns) tableNetCost := netCostVer2(option, rows, rowSize, netFactor) tableChildCost, err := tablePath.getPlanCostVer2(taskType, option) @@ -297,7 +303,7 @@ func (p *PhysicalIndexMergeReader) getPlanCostVer2(taskType property.TaskType, o indexSideCost := make([]costVer2, 0, len(p.partialPlans)) for _, indexPath := range p.partialPlans { rows := getCardinality(indexPath, option.CostFlag) - rowSize := getAvgRowSize(indexPath.Stats(), indexPath.Schema()) + rowSize := getAvgRowSize(indexPath.Stats(), indexPath.Schema().Columns) indexNetCost := netCostVer2(option, rows, rowSize, netFactor) indexChildCost, err := indexPath.getPlanCostVer2(taskType, option) @@ -329,7 +335,7 @@ func (p *PhysicalSort) getPlanCostVer2(taskType property.TaskType, option *PlanC } rows := math.Max(getCardinality(p.children[0], option.CostFlag), 1) - rowSize := getAvgRowSize(p.statsInfo(), p.Schema()) + rowSize := getAvgRowSize(p.statsInfo(), p.Schema().Columns) cpuFactor := getTaskCPUFactorVer2(p, taskType) memFactor := getTaskMemFactorVer2(p, taskType) diskFactor := defaultVer2Factors.TiDBDisk @@ -378,7 +384,7 @@ func (p *PhysicalTopN) getPlanCostVer2(taskType property.TaskType, option *PlanC rows := getCardinality(p.children[0], option.CostFlag) N := math.Max(1, float64(p.Count+p.Offset)) - rowSize := getAvgRowSize(p.statsInfo(), p.Schema()) + rowSize := getAvgRowSize(p.statsInfo(), p.Schema().Columns) cpuFactor := getTaskCPUFactorVer2(p, taskType) memFactor := getTaskMemFactorVer2(p, taskType) @@ -429,7 +435,7 @@ func (p *PhysicalHashAgg) getPlanCostVer2(taskType property.TaskType, option *Pl inputRows := getCardinality(p.children[0], option.CostFlag) outputRows := getCardinality(p, option.CostFlag) - outputRowSize := getAvgRowSize(p.Stats(), p.Schema()) + outputRowSize := getAvgRowSize(p.Stats(), p.Schema().Columns) cpuFactor := getTaskCPUFactorVer2(p, taskType) memFactor := getTaskMemFactorVer2(p, taskType) concurrency := float64(p.ctx.GetSessionVars().HashAggFinalConcurrency()) @@ -501,7 +507,7 @@ func (p *PhysicalHashJoin) getPlanCostVer2(taskType property.TaskType, option *P } buildRows := getCardinality(build, option.CostFlag) probeRows := getCardinality(probe, option.CostFlag) - buildRowSize := getAvgRowSize(build.Stats(), build.Schema()) + buildRowSize := getAvgRowSize(build.Stats(), build.Schema().Columns) tidbConcurrency := float64(p.Concurrency) mppConcurrency := float64(3) // TODO: remove this empirical value cpuFactor := getTaskCPUFactorVer2(p, taskType) @@ -645,7 +651,7 @@ func (p *PhysicalExchangeReceiver) getPlanCostVer2(taskType property.TaskType, o } rows := getCardinality(p, option.CostFlag) - rowSize := getAvgRowSize(p.stats, p.Schema()) + rowSize := getAvgRowSize(p.stats, p.Schema().Columns) netFactor := getTaskNetFactorVer2(p, taskType) isBCast := false if sender, ok := p.children[0].(*PhysicalExchangeSender); ok { @@ -678,7 +684,7 @@ func (p *PointGetPlan) getPlanCostVer2(taskType property.TaskType, option *PlanC p.planCostInit = true return zeroCostVer2, nil } - rowSize := getAvgRowSize(p.stats, p.schema) + rowSize := getAvgRowSize(p.stats, p.schema.Columns) netFactor := getTaskNetFactorVer2(p, taskType) p.planCostVer2 = netCostVer2(option, 1, rowSize, netFactor) @@ -698,7 +704,7 @@ func (p *BatchPointGetPlan) getPlanCostVer2(taskType property.TaskType, option * return zeroCostVer2, nil } rows := getCardinality(p, option.CostFlag) - rowSize := getAvgRowSize(p.stats, p.schema) + rowSize := getAvgRowSize(p.stats, p.schema.Columns) netFactor := getTaskNetFactorVer2(p, taskType) p.planCostVer2 = netCostVer2(option, rows, rowSize, netFactor) diff --git a/planner/core/plan_cost_ver2_test.go b/planner/core/plan_cost_ver2_test.go index 0043aa0be898e..27b5b913980e4 100644 --- a/planner/core/plan_cost_ver2_test.go +++ b/planner/core/plan_cost_ver2_test.go @@ -142,15 +142,55 @@ func TestCostModelShowFormula(t *testing.T) { actual := make([][]interface{}, 0, len(plan)) for _, row := range plan { actual = append(actual, []interface{}{row[0], row[3]}) // id,costFormula - fmt.Println(actual) } require.Equal(t, actual, [][]interface{}{ {"TableReader_7", "((Selection_6) + (net(2*rowsize(16)*tidb_kv_net_factor(3.96))))/15"}, {"└─Selection_6", "(cpu(3*filters(1)*tikv_cpu_factor(49.9))) + (TableFullScan_5)"}, - {" └─TableFullScan_5", "scan(3*logrowsize(29)*tikv_scan_factor(40.7))"}, + {" └─TableFullScan_5", "scan(3*logrowsize(32)*tikv_scan_factor(40.7))"}, }) } +func TestCostModelVer2ScanRowSize(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec(`create table t (pk int, a int, b int, c int, d int, primary key(pk), index ab(a, b), index abc(a, b, c))`) + tk.MustExec("insert into t values (1, 1, 1, 1, 1)") + tk.MustExec(`set @@tidb_cost_model_version=2`) + + cases := []struct { + query string + scanFormula string + }{ + // index scan row-size on idx_ab is always equal to row-size(index_ab) + {"select a from t use index(ab) where a=1", "scan(1*logrowsize(32)*tikv_scan_factor(40.7))"}, + {"select a, b from t use index(ab) where a=1", "scan(1*logrowsize(32)*tikv_scan_factor(40.7))"}, + {"select b from t use index(ab) where a=1 and b=1", "scan(1*logrowsize(32)*tikv_scan_factor(40.7))"}, + // index scan row-size on idx_abc is always equal to row-size(index_abc) + {"select a from t use index(abc) where a=1", "scan(1*logrowsize(48)*tikv_scan_factor(40.7))"}, + {"select a from t use index(abc) where a=1 and b=1", "scan(1*logrowsize(48)*tikv_scan_factor(40.7))"}, + {"select a, b from t use index(abc) where a=1 and b=1", "scan(1*logrowsize(48)*tikv_scan_factor(40.7))"}, + {"select a, b, c from t use index(abc) where a=1 and b=1 and c=1", "scan(1*logrowsize(48)*tikv_scan_factor(40.7))"}, + // table scan row-size is always equal to row-size(*) + {"select a from t use index(primary) where a=1", "scan(1*logrowsize(80)*tikv_scan_factor(40.7))"}, + {"select a, d from t use index(primary) where a=1", "scan(1*logrowsize(80)*tikv_scan_factor(40.7))"}, + {"select * from t use index(primary) where a=1", "scan(1*logrowsize(80)*tikv_scan_factor(40.7))"}, + } + for _, c := range cases { + rs := tk.MustQuery("explain analyze format=true_card_cost " + c.query).Rows() + scan := rs[len(rs)-1] + formula := scan[3] + require.Equal(t, formula, c.scanFormula) + } + + tk.MustQuery("explain select a from t where a=1").Check(testkit.Rows( + `IndexReader_6 10.00 root index:IndexRangeScan_5`, // use idx_ab automatically since it has the smallest row-size in all access paths. + `└─IndexRangeScan_5 10.00 cop[tikv] table:t, index:ab(a, b) range:[1,1], keep order:false, stats:pseudo`)) + tk.MustQuery("explain select a, b, c from t where a=1").Check(testkit.Rows( + `IndexReader_6 10.00 root index:IndexRangeScan_5`, // use idx_abc automatically + `└─IndexRangeScan_5 10.00 cop[tikv] table:t, index:abc(a, b, c) range:[1,1], keep order:false, stats:pseudo`)) +} + func TestCostModelTraceVer2(t *testing.T) { store := testkit.CreateMockStore(t) tk := testkit.NewTestKit(t, store) diff --git a/planner/core/task.go b/planner/core/task.go index 44295ca6b4def..11d502568d3ae 100644 --- a/planner/core/task.go +++ b/planner/core/task.go @@ -297,12 +297,11 @@ func (p *PhysicalIndexJoin) attach2Task(tasks ...task) task { return t } -func getAvgRowSize(stats *property.StatsInfo, schema *expression.Schema) (size float64) { +func getAvgRowSize(stats *property.StatsInfo, cols []*expression.Column) (size float64) { if stats.HistColl != nil { - size = stats.HistColl.GetAvgRowSizeListInDisk(schema.Columns) + size = stats.HistColl.GetAvgRowSizeListInDisk(cols) } else { // Estimate using just the type info. - cols := schema.Columns for _, col := range cols { size += float64(chunk.EstimateTypeWidth(col.GetType())) } diff --git a/planner/core/testdata/enforce_mpp_suite_out.json b/planner/core/testdata/enforce_mpp_suite_out.json index 20f349233aed4..3f8a2667a4dc2 100644 --- a/planner/core/testdata/enforce_mpp_suite_out.json +++ b/planner/core/testdata/enforce_mpp_suite_out.json @@ -31,30 +31,30 @@ { "SQL": "explain format='verbose' select count(*) from t where a=1", "Plan": [ - "StreamAgg_24 1.00 217.09 root funcs:count(Column#6)->Column#4", - "└─IndexReader_25 1.00 167.19 root index:StreamAgg_9", - " └─StreamAgg_9 1.00 2476.20 cop[tikv] funcs:count(1)->Column#6", - " └─IndexRangeScan_23 10.00 1977.20 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" + "StreamAgg_24 1.00 193.81 root funcs:count(Column#6)->Column#4", + "└─IndexReader_25 1.00 143.91 root index:StreamAgg_9", + " └─StreamAgg_9 1.00 2127.00 cop[tikv] funcs:count(1)->Column#6", + " └─IndexRangeScan_23 10.00 1628.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" ], "Warn": null }, { "SQL": "explain format='verbose' select /*+ read_from_storage(tikv[t]) */ count(*) from t where a=1", "Plan": [ - "StreamAgg_17 1.00 217.09 root funcs:count(Column#6)->Column#4", - "└─IndexReader_18 1.00 167.19 root index:StreamAgg_9", - " └─StreamAgg_9 1.00 2476.20 cop[tikv] funcs:count(1)->Column#6", - " └─IndexRangeScan_16 10.00 1977.20 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" + "StreamAgg_17 1.00 193.81 root funcs:count(Column#6)->Column#4", + "└─IndexReader_18 1.00 143.91 root index:StreamAgg_9", + " └─StreamAgg_9 1.00 2127.00 cop[tikv] funcs:count(1)->Column#6", + " └─IndexRangeScan_16 10.00 1628.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" ], "Warn": null }, { "SQL": "explain format='verbose' select /*+ read_from_storage(tiflash[t]) */ count(*) from t where a=1", "Plan": [ - "StreamAgg_10 1.00 65360.67 root funcs:count(1)->Column#4", - "└─TableReader_24 10.00 64861.67 root data:Selection_23", - " └─Selection_23 10.00 972291.38 cop[tiflash] eq(test.t.a, 1)", - " └─TableFullScan_22 10000.00 948291.38 cop[tiflash] table:t keep order:false, stats:pseudo" + "StreamAgg_10 1.00 64007.91 root funcs:count(1)->Column#4", + "└─TableReader_24 10.00 63508.91 root data:Selection_23", + " └─Selection_23 10.00 952000.00 cop[tiflash] eq(test.t.a, 1)", + " └─TableFullScan_22 10000.00 928000.00 cop[tiflash] table:t keep order:false, stats:pseudo" ], "Warn": null }, @@ -71,30 +71,30 @@ { "SQL": "explain format='verbose' select count(*) from t where a=1", "Plan": [ - "StreamAgg_31 1.00 217.09 root funcs:count(Column#7)->Column#4", - "└─IndexReader_32 1.00 167.19 root index:StreamAgg_11", - " └─StreamAgg_11 1.00 2476.20 cop[tikv] funcs:count(1)->Column#7", - " └─IndexRangeScan_30 10.00 1977.20 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" + "StreamAgg_31 1.00 193.81 root funcs:count(Column#7)->Column#4", + "└─IndexReader_32 1.00 143.91 root index:StreamAgg_11", + " └─StreamAgg_11 1.00 2127.00 cop[tikv] funcs:count(1)->Column#7", + " └─IndexRangeScan_30 10.00 1628.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" ], "Warn": null }, { "SQL": "explain format='verbose' select /*+ read_from_storage(tikv[t]) */ count(*) from t where a=1", "Plan": [ - "StreamAgg_19 1.00 217.09 root funcs:count(Column#6)->Column#4", - "└─IndexReader_20 1.00 167.19 root index:StreamAgg_11", - " └─StreamAgg_11 1.00 2476.20 cop[tikv] funcs:count(1)->Column#6", - " └─IndexRangeScan_18 10.00 1977.20 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" + "StreamAgg_19 1.00 193.81 root funcs:count(Column#6)->Column#4", + "└─IndexReader_20 1.00 143.91 root index:StreamAgg_11", + " └─StreamAgg_11 1.00 2127.00 cop[tikv] funcs:count(1)->Column#6", + " └─IndexRangeScan_18 10.00 1628.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" ], "Warn": null }, { "SQL": "explain format='verbose' select /*+ read_from_storage(tiflash[t]) */ count(*) from t where a=1", "Plan": [ - "StreamAgg_12 1.00 65360.67 root funcs:count(1)->Column#4", - "└─TableReader_31 10.00 64861.67 root data:Selection_30", - " └─Selection_30 10.00 972291.38 cop[tiflash] eq(test.t.a, 1)", - " └─TableFullScan_29 10000.00 948291.38 cop[tiflash] table:t keep order:false, stats:pseudo" + "StreamAgg_12 1.00 64007.91 root funcs:count(1)->Column#4", + "└─TableReader_31 10.00 63508.91 root data:Selection_30", + " └─Selection_30 10.00 952000.00 cop[tiflash] eq(test.t.a, 1)", + " └─TableFullScan_29 10000.00 928000.00 cop[tiflash] table:t keep order:false, stats:pseudo" ], "Warn": null }, @@ -106,30 +106,30 @@ { "SQL": "explain format='verbose' select count(*) from t where a=1", "Plan": [ - "StreamAgg_31 1.00 217.09 root funcs:count(Column#7)->Column#4", - "└─IndexReader_32 1.00 167.19 root index:StreamAgg_11", - " └─StreamAgg_11 1.00 2476.20 cop[tikv] funcs:count(1)->Column#7", - " └─IndexRangeScan_30 10.00 1977.20 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" + "StreamAgg_31 1.00 193.81 root funcs:count(Column#7)->Column#4", + "└─IndexReader_32 1.00 143.91 root index:StreamAgg_11", + " └─StreamAgg_11 1.00 2127.00 cop[tikv] funcs:count(1)->Column#7", + " └─IndexRangeScan_30 10.00 1628.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" ], "Warn": null }, { "SQL": "explain format='verbose' select /*+ read_from_storage(tikv[t]) */ count(*) from t where a=1", "Plan": [ - "StreamAgg_19 1.00 217.09 root funcs:count(Column#6)->Column#4", - "└─IndexReader_20 1.00 167.19 root index:StreamAgg_11", - " └─StreamAgg_11 1.00 2476.20 cop[tikv] funcs:count(1)->Column#6", - " └─IndexRangeScan_18 10.00 1977.20 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" + "StreamAgg_19 1.00 193.81 root funcs:count(Column#6)->Column#4", + "└─IndexReader_20 1.00 143.91 root index:StreamAgg_11", + " └─StreamAgg_11 1.00 2127.00 cop[tikv] funcs:count(1)->Column#6", + " └─IndexRangeScan_18 10.00 1628.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" ], "Warn": null }, { "SQL": "explain format='verbose' select /*+ read_from_storage(tiflash[t]) */ count(*) from t where a=1", "Plan": [ - "StreamAgg_12 1.00 65360.67 root funcs:count(1)->Column#4", - "└─TableReader_31 10.00 64861.67 root data:Selection_30", - " └─Selection_30 10.00 972291.38 cop[tiflash] eq(test.t.a, 1)", - " └─TableFullScan_29 10000.00 948291.38 cop[tiflash] table:t keep order:false, stats:pseudo" + "StreamAgg_12 1.00 64007.91 root funcs:count(1)->Column#4", + "└─TableReader_31 10.00 63508.91 root data:Selection_30", + " └─Selection_30 10.00 952000.00 cop[tiflash] eq(test.t.a, 1)", + " └─TableFullScan_29 10000.00 928000.00 cop[tiflash] table:t keep order:false, stats:pseudo" ], "Warn": null }, @@ -141,20 +141,20 @@ { "SQL": "explain format='verbose' select count(*) from t where a=1", "Plan": [ - "StreamAgg_31 1.00 217.09 root funcs:count(Column#7)->Column#4", - "└─IndexReader_32 1.00 167.19 root index:StreamAgg_11", - " └─StreamAgg_11 1.00 2476.20 cop[tikv] funcs:count(1)->Column#7", - " └─IndexRangeScan_30 10.00 1977.20 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" + "StreamAgg_31 1.00 193.81 root funcs:count(Column#7)->Column#4", + "└─IndexReader_32 1.00 143.91 root index:StreamAgg_11", + " └─StreamAgg_11 1.00 2127.00 cop[tikv] funcs:count(1)->Column#7", + " └─IndexRangeScan_30 10.00 1628.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" ], "Warn": null }, { "SQL": "explain format='verbose' select /*+ read_from_storage(tikv[t]) */ count(*) from t where a=1", "Plan": [ - "StreamAgg_19 1.00 217.09 root funcs:count(Column#6)->Column#4", - "└─IndexReader_20 1.00 167.19 root index:StreamAgg_11", - " └─StreamAgg_11 1.00 2476.20 cop[tikv] funcs:count(1)->Column#6", - " └─IndexRangeScan_18 10.00 1977.20 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" + "StreamAgg_19 1.00 193.81 root funcs:count(Column#6)->Column#4", + "└─IndexReader_20 1.00 143.91 root index:StreamAgg_11", + " └─StreamAgg_11 1.00 2127.00 cop[tikv] funcs:count(1)->Column#6", + " └─IndexRangeScan_18 10.00 1628.00 cop[tikv] table:t, index:idx(a) range:[1,1], keep order:false, stats:pseudo" ], "Warn": [ "MPP mode may be blocked because you have set a hint to read table `t` from TiKV." @@ -165,10 +165,10 @@ "Plan": [ "HashAgg_22 1.00 39930.30 root funcs:count(Column#6)->Column#4", "└─TableReader_24 1.00 0.00 root data:ExchangeSender_23", - " └─ExchangeSender_23 1.00 974211.94 mpp[tiflash] ExchangeType: PassThrough", - " └─HashAgg_10 1.00 974211.94 mpp[tiflash] funcs:count(1)->Column#6", - " └─Selection_21 10.00 972291.38 mpp[tiflash] eq(test.t.a, 1)", - " └─TableFullScan_20 10000.00 948291.38 mpp[tiflash] table:t keep order:false, stats:pseudo" + " └─ExchangeSender_23 1.00 953920.56 mpp[tiflash] ExchangeType: PassThrough", + " └─HashAgg_10 1.00 953920.56 mpp[tiflash] funcs:count(1)->Column#6", + " └─Selection_21 10.00 952000.00 mpp[tiflash] eq(test.t.a, 1)", + " └─TableFullScan_20 10000.00 928000.00 mpp[tiflash] table:t keep order:false, stats:pseudo" ], "Warn": null } diff --git a/planner/core/testdata/integration_suite_out.json b/planner/core/testdata/integration_suite_out.json index 0a04a8f55f24d..e223d6604e3f1 100644 --- a/planner/core/testdata/integration_suite_out.json +++ b/planner/core/testdata/integration_suite_out.json @@ -1861,8 +1861,8 @@ { "SQL": "select f, g from t1 where f = 2 and g > 3", "Plan": [ - "IndexReader_6 33.33 752.77 root index:IndexRangeScan_5", - "└─IndexRangeScan_5 33.33 7067.49 cop[tikv] table:t1, index:f_g(f, g) range:(2 3,2 +inf], keep order:false, stats:pseudo" + "IndexReader_6 33.33 733.82 root index:IndexRangeScan_5", + "└─IndexRangeScan_5 33.33 6783.33 cop[tikv] table:t1, index:f_g(f, g) range:(2 3,2 +inf], keep order:false, stats:pseudo" ], "Warnings": [ "Note 1105 unique index f_g of t1 is selected since the path only fetches limited number of rows with single scan" @@ -2486,65 +2486,65 @@ { "SQL": "explain format = 'verbose' select count(*) from t3", "Plan": [ - "StreamAgg_20 1.00 99.31 root funcs:count(Column#9)->Column#4", - "└─TableReader_21 1.00 49.41 root data:StreamAgg_8", - " └─StreamAgg_8 1.00 709.52 cop[tikv] funcs:count(1)->Column#9", - " └─TableFullScan_18 3.00 559.82 cop[tikv] table:t3 keep order:false" + "StreamAgg_20 1.00 102.69 root funcs:count(Column#9)->Column#4", + "└─IndexReader_21 1.00 52.79 root index:StreamAgg_8", + " └─StreamAgg_8 1.00 760.20 cop[tikv] funcs:count(1)->Column#9", + " └─IndexFullScan_19 3.00 610.50 cop[tikv] table:t3, index:c(b) keep order:false" ] }, { "SQL": "explain format = 'verbose' select count(*) from t2", "Plan": [ - "StreamAgg_26 1.00 99.31 root funcs:count(Column#7)->Column#4", - "└─TableReader_27 1.00 49.41 root data:StreamAgg_10", - " └─StreamAgg_10 1.00 709.52 cop[tikv] funcs:count(1)->Column#7", - " └─TableFullScan_24 3.00 559.82 cop[tikv] table:t2 keep order:false" + "StreamAgg_26 1.00 107.45 root funcs:count(Column#7)->Column#4", + "└─TableReader_27 1.00 57.55 root data:StreamAgg_10", + " └─StreamAgg_10 1.00 831.62 cop[tikv] funcs:count(1)->Column#7", + " └─TableFullScan_24 3.00 681.92 cop[tikv] table:t2 keep order:false" ] }, { "SQL": "explain format = 'verbose' select * from t3 order by a", "Plan": [ - "Sort_4 3.00 310.13 root test.t3.a", - "└─TableReader_8 3.00 62.67 root data:TableFullScan_7", - " └─TableFullScan_7 3.00 559.82 cop[tikv] table:t3 keep order:false" + "Sort_4 3.00 318.27 root test.t3.a", + "└─TableReader_8 3.00 70.81 root data:TableFullScan_7", + " └─TableFullScan_7 3.00 681.92 cop[tikv] table:t3 keep order:false" ] }, { "SQL": "explain format = 'verbose' select * from t3 order by b", "Plan": [ - "Sort_4 3.00 310.13 root test.t3.b", - "└─TableReader_8 3.00 62.67 root data:TableFullScan_7", - " └─TableFullScan_7 3.00 559.82 cop[tikv] table:t3 keep order:false" + "Sort_4 3.00 318.27 root test.t3.b", + "└─TableReader_8 3.00 70.81 root data:TableFullScan_7", + " └─TableFullScan_7 3.00 681.92 cop[tikv] table:t3 keep order:false" ] }, { "SQL": "explain format = 'verbose' select * from t3 order by a limit 1", "Plan": [ - "TopN_7 1.00 44.96 root test.t3.a, offset:0, count:1", - "└─TableReader_16 1.00 41.76 root data:TopN_15", - " └─TopN_15 1.00 563.02 cop[tikv] test.t3.a, offset:0, count:1", - " └─TableFullScan_14 3.00 559.82 cop[tikv] table:t3 keep order:false" + "TopN_7 1.00 53.10 root test.t3.a, offset:0, count:1", + "└─TableReader_16 1.00 49.90 root data:TopN_15", + " └─TopN_15 1.00 685.12 cop[tikv] test.t3.a, offset:0, count:1", + " └─TableFullScan_14 3.00 681.92 cop[tikv] table:t3 keep order:false" ] }, { "SQL": "explain format = 'verbose' select * from t3 order by b limit 1", "Plan": [ - "TopN_7 1.00 44.96 root test.t3.b, offset:0, count:1", - "└─TableReader_16 1.00 41.76 root data:TopN_15", - " └─TopN_15 1.00 563.02 cop[tikv] test.t3.b, offset:0, count:1", - " └─TableFullScan_14 3.00 559.82 cop[tikv] table:t3 keep order:false" + "TopN_7 1.00 53.10 root test.t3.b, offset:0, count:1", + "└─TableReader_16 1.00 49.90 root data:TopN_15", + " └─TopN_15 1.00 685.12 cop[tikv] test.t3.b, offset:0, count:1", + " └─TableFullScan_14 3.00 681.92 cop[tikv] table:t3 keep order:false" ] }, { "SQL": "explain format = 'verbose' select count(*) from t2 group by a", "Plan": [ - "TableReader_44 3.00 25896.85 root data:ExchangeSender_43", - "└─ExchangeSender_43 3.00 388400.01 mpp[tiflash] ExchangeType: PassThrough", - " └─Projection_38 3.00 388400.00 mpp[tiflash] Column#4", - " └─HashAgg_36 3.00 388399.98 mpp[tiflash] group by:test.t2.a, funcs:count(1)->Column#4", - " └─ExchangeReceiver_22 3.00 385507.26 mpp[tiflash] ", - " └─ExchangeSender_21 3.00 385459.26 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t2.a, collate: binary]", - " └─TableFullScan_20 3.00 385459.26 mpp[tiflash] table:t2 keep order:false" + "TableReader_44 3.00 31142.18 root data:ExchangeSender_43", + "└─ExchangeSender_43 3.00 467079.95 mpp[tiflash] ExchangeType: PassThrough", + " └─Projection_38 3.00 467079.93 mpp[tiflash] Column#4", + " └─HashAgg_36 3.00 467079.92 mpp[tiflash] group by:test.t2.a, funcs:count(1)->Column#4", + " └─ExchangeReceiver_22 3.00 464187.20 mpp[tiflash] ", + " └─ExchangeSender_21 3.00 464139.20 mpp[tiflash] ExchangeType: HashPartition, Hash Cols: [name: test.t2.a, collate: binary]", + " └─TableFullScan_20 3.00 464139.20 mpp[tiflash] table:t2 keep order:false" ] }, { @@ -2567,90 +2567,90 @@ { "SQL": "explain format = 'verbose' select count(*) from t2 where a = 0", "Plan": [ - "StreamAgg_12 1.00 47.30 root funcs:count(1)->Column#4", - "└─TableReader_21 0.00 47.30 root data:Selection_20", - " └─Selection_20 0.00 709.52 cop[tikv] eq(test.t2.a, 0)", - " └─TableFullScan_19 3.00 559.82 cop[tikv] table:t2 keep order:false" + "StreamAgg_12 1.00 55.44 root funcs:count(1)->Column#4", + "└─TableReader_21 0.00 55.44 root data:Selection_20", + " └─Selection_20 0.00 831.62 cop[tikv] eq(test.t2.a, 0)", + " └─TableFullScan_19 3.00 681.92 cop[tikv] table:t2 keep order:false" ] }, { "SQL": "explain format = 'verbose' select count(*) from t3 t join t3 on t.a = t3.b", "Plan": [ - "StreamAgg_10 1.00 630.77 root funcs:count(1)->Column#7", - "└─HashJoin_40 3.00 481.07 root inner join, equal:[eq(test.t3.a, test.t3.b)]", - " ├─IndexReader_28(Build) 3.00 52.22 root index:IndexFullScan_27", - " │ └─IndexFullScan_27 3.00 593.16 cop[tikv] table:t3, index:c(b) keep order:false", - " └─TableReader_26(Probe) 3.00 59.97 root data:Selection_25", - " └─Selection_25 3.00 709.52 cop[tikv] not(isnull(test.t3.a))", - " └─TableFullScan_24 3.00 559.82 cop[tikv] table:t keep order:false" + "StreamAgg_10 1.00 631.93 root funcs:count(1)->Column#7", + "└─HashJoin_40 3.00 482.23 root inner join, equal:[eq(test.t3.a, test.t3.b)]", + " ├─IndexReader_28(Build) 3.00 45.23 root index:IndexFullScan_27", + " │ └─IndexFullScan_27 3.00 488.40 cop[tikv] table:t3, index:c(b) keep order:false", + " └─TableReader_26(Probe) 3.00 68.11 root data:Selection_25", + " └─Selection_25 3.00 831.62 cop[tikv] not(isnull(test.t3.a))", + " └─TableFullScan_24 3.00 681.92 cop[tikv] table:t keep order:false" ] }, { "SQL": "explain format = 'verbose' select /*+ read_from_storage(tiflash[t1, t2]) */ count(*) from t1 join t2 on t1.a = t2.a", "Plan": [ - "StreamAgg_15 1.00 51562.56 root funcs:count(1)->Column#7", - "└─TableReader_41 3.00 51412.86 root data:ExchangeSender_40", - " └─ExchangeSender_40 3.00 771087.32 mpp[tiflash] ExchangeType: PassThrough", - " └─HashJoin_37 3.00 771087.32 mpp[tiflash] inner join, equal:[eq(test.t1.a, test.t2.a)]", - " ├─ExchangeReceiver_22(Build) 3.00 385610.46 mpp[tiflash] ", - " │ └─ExchangeSender_21 3.00 385466.46 mpp[tiflash] ExchangeType: Broadcast", - " │ └─Selection_20 3.00 385466.46 mpp[tiflash] not(isnull(test.t1.a))", - " │ └─TableFullScan_19 3.00 385459.26 mpp[tiflash] table:t1 keep order:false", - " └─Selection_24(Probe) 3.00 385466.46 mpp[tiflash] not(isnull(test.t2.a))", - " └─TableFullScan_23 3.00 385459.26 mpp[tiflash] table:t2 keep order:false" + "StreamAgg_15 1.00 62053.22 root funcs:count(1)->Column#7", + "└─TableReader_41 3.00 61903.52 root data:ExchangeSender_40", + " └─ExchangeSender_40 3.00 928447.20 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin_37 3.00 928447.20 mpp[tiflash] inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─ExchangeReceiver_22(Build) 3.00 464290.40 mpp[tiflash] ", + " │ └─ExchangeSender_21 3.00 464146.40 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection_20 3.00 464146.40 mpp[tiflash] not(isnull(test.t1.a))", + " │ └─TableFullScan_19 3.00 464139.20 mpp[tiflash] table:t1 keep order:false", + " └─Selection_24(Probe) 3.00 464146.40 mpp[tiflash] not(isnull(test.t2.a))", + " └─TableFullScan_23 3.00 464139.20 mpp[tiflash] table:t2 keep order:false" ] }, { "SQL": "explain format = 'verbose' select /*+ read_from_storage(tiflash[t1, t2]) */ count(*) from t1 join t2 on t1.a = t2.a join t3 on t1.b = t3.b", "Plan": [ - "StreamAgg_15 1.00 54032.05 root funcs:count(1)->Column#10", - "└─HashJoin_59 3.00 53882.35 root inner join, equal:[eq(test.t1.b, test.t3.b)]", - " ├─IndexReader_47(Build) 3.00 52.22 root index:IndexFullScan_46", - " │ └─IndexFullScan_46 3.00 593.16 cop[tikv] table:t3, index:c(b) keep order:false", - " └─TableReader_39(Probe) 3.00 53461.26 root data:ExchangeSender_38", - " └─ExchangeSender_38 3.00 801760.47 mpp[tiflash] ExchangeType: PassThrough", - " └─HashJoin_29 3.00 801760.47 mpp[tiflash] inner join, equal:[eq(test.t1.a, test.t2.a)]", - " ├─ExchangeReceiver_35(Build) 3.00 416282.81 mpp[tiflash] ", - " │ └─ExchangeSender_34 3.00 415994.81 mpp[tiflash] ExchangeType: Broadcast", - " │ └─Selection_33 3.00 415994.81 mpp[tiflash] not(isnull(test.t1.a)), not(isnull(test.t1.b))", - " │ └─TableFullScan_32 3.00 415980.41 mpp[tiflash] table:t1 keep order:false", - " └─Selection_37(Probe) 3.00 385466.46 mpp[tiflash] not(isnull(test.t2.a))", - " └─TableFullScan_36 3.00 385459.26 mpp[tiflash] table:t2 keep order:false" + "StreamAgg_15 1.00 70216.64 root funcs:count(1)->Column#10", + "└─HashJoin_59 3.00 70066.94 root inner join, equal:[eq(test.t1.b, test.t3.b)]", + " ├─IndexReader_47(Build) 3.00 45.23 root index:IndexFullScan_46", + " │ └─IndexFullScan_46 3.00 488.40 cop[tikv] table:t3, index:c(b) keep order:false", + " └─TableReader_39(Probe) 3.00 69652.83 root data:ExchangeSender_38", + " └─ExchangeSender_38 3.00 1044634.00 mpp[tiflash] ExchangeType: PassThrough", + " └─HashJoin_29 3.00 1044634.00 mpp[tiflash] inner join, equal:[eq(test.t1.a, test.t2.a)]", + " ├─ExchangeReceiver_35(Build) 3.00 580476.40 mpp[tiflash] ", + " │ └─ExchangeSender_34 3.00 580188.40 mpp[tiflash] ExchangeType: Broadcast", + " │ └─Selection_33 3.00 580188.40 mpp[tiflash] not(isnull(test.t1.a)), not(isnull(test.t1.b))", + " │ └─TableFullScan_32 3.00 580174.00 mpp[tiflash] table:t1 keep order:false", + " └─Selection_37(Probe) 3.00 464146.40 mpp[tiflash] not(isnull(test.t2.a))", + " └─TableFullScan_36 3.00 464139.20 mpp[tiflash] table:t2 keep order:false" ] }, { "SQL": "explain format = 'verbose' select (2) in (select /*+ read_from_storage(tiflash[t1]) */ count(*) from t1) from (select t.b < (select /*+ read_from_storage(tiflash[t2]) */ t.b from t2 limit 1 ) from t3 t) t", "Plan": [ - "HashJoin_19 3.00 110724.79 root CARTESIAN left outer semi join", - "├─Selection_38(Build) 0.80 24733.71 root eq(2, Column#18)", - "│ └─StreamAgg_45 1.00 24683.81 root funcs:count(1)->Column#18", - "│ └─TableReader_59 3.00 24534.11 root data:TableFullScan_58", - "│ └─TableFullScan_58 3.00 367821.61 cop[tiflash] table:t1 keep order:false", - "└─Projection_20(Probe) 3.00 85919.94 root 1->Column#28", - " └─Apply_22 3.00 85919.64 root CARTESIAN left outer join", - " ├─TableReader_24(Build) 3.00 49.99 root data:TableFullScan_23", - " │ └─TableFullScan_23 3.00 559.82 cop[tikv] table:t keep order:false", - " └─Projection_27(Probe) 3.00 28623.22 root 1->Column#26", - " └─Limit_30 3.00 28623.12 root offset:0, count:1", - " └─TableReader_37 3.00 28623.12 root data:ExchangeSender_36", - " └─ExchangeSender_36 3.00 429293.93 mpp[tiflash] ExchangeType: PassThrough", - " └─Limit_35 3.00 429293.93 mpp[tiflash] offset:0, count:1", - " └─TableFullScan_34 3.00 429293.93 mpp[tiflash] table:t2 keep order:false" + "HashJoin_19 3.00 160879.40 root CARTESIAN left outer semi join", + "├─Selection_38(Build) 0.80 31154.89 root eq(2, Column#18)", + "│ └─StreamAgg_45 1.00 31104.99 root funcs:count(1)->Column#18", + "│ └─TableReader_59 3.00 30955.29 root data:TableFullScan_58", + "│ └─TableFullScan_58 3.00 464139.20 cop[tiflash] table:t1 keep order:false", + "└─Projection_20(Probe) 3.00 129653.38 root 1->Column#28", + " └─Apply_22 3.00 129653.08 root CARTESIAN left outer join", + " ├─TableReader_24(Build) 3.00 58.13 root data:TableFullScan_23", + " │ └─TableFullScan_23 3.00 681.92 cop[tikv] table:t keep order:false", + " └─Projection_27(Probe) 3.00 43198.32 root 1->Column#26", + " └─Limit_30 3.00 43198.22 root offset:0, count:1", + " └─TableReader_37 3.00 43198.22 root data:ExchangeSender_36", + " └─ExchangeSender_36 3.00 647920.44 mpp[tiflash] ExchangeType: PassThrough", + " └─Limit_35 3.00 647920.44 mpp[tiflash] offset:0, count:1", + " └─TableFullScan_34 3.00 647920.44 mpp[tiflash] table:t2 keep order:false" ] }, { "SQL": "explain format = 'verbose' select /*+ merge_join(t1), read_from_storage(tiflash[t1, t2]) */ count(*) from t1 join t2 on t1.a = t2.a", "Plan": [ - "StreamAgg_14 1.00 52067.30 root funcs:count(1)->Column#7", - "└─MergeJoin_26 3.00 51917.60 root inner join, left key:test.t1.a, right key:test.t2.a", - " ├─Sort_24(Build) 3.00 25957.31 root test.t2.a", - " │ └─TableReader_23 3.00 25710.44 root data:Selection_22", - " │ └─Selection_22 3.00 385466.46 cop[tiflash] not(isnull(test.t2.a))", - " │ └─TableFullScan_21 3.00 385459.26 cop[tiflash] table:t2 keep order:false", - " └─Sort_20(Probe) 3.00 25957.31 root test.t1.a", - " └─TableReader_19 3.00 25710.44 root data:Selection_18", - " └─Selection_18 3.00 385466.46 cop[tiflash] not(isnull(test.t1.a))", - " └─TableFullScan_17 3.00 385459.26 cop[tiflash] table:t1 keep order:false" + "StreamAgg_14 1.00 62557.96 root funcs:count(1)->Column#7", + "└─MergeJoin_26 3.00 62408.26 root inner join, left key:test.t1.a, right key:test.t2.a", + " ├─Sort_24(Build) 3.00 31202.63 root test.t2.a", + " │ └─TableReader_23 3.00 30955.77 root data:Selection_22", + " │ └─Selection_22 3.00 464146.40 cop[tiflash] not(isnull(test.t2.a))", + " │ └─TableFullScan_21 3.00 464139.20 cop[tiflash] table:t2 keep order:false", + " └─Sort_20(Probe) 3.00 31202.63 root test.t1.a", + " └─TableReader_19 3.00 30955.77 root data:Selection_18", + " └─Selection_18 3.00 464146.40 cop[tiflash] not(isnull(test.t1.a))", + " └─TableFullScan_17 3.00 464139.20 cop[tiflash] table:t1 keep order:false" ] } ] diff --git a/planner/core/testdata/join_reorder_suite_out.json b/planner/core/testdata/join_reorder_suite_out.json index 829a2683b4775..e17cbae1f3b3d 100644 --- a/planner/core/testdata/join_reorder_suite_out.json +++ b/planner/core/testdata/join_reorder_suite_out.json @@ -6333,8 +6333,8 @@ "SQL": "select /*+ straight_join() */ * from t1 join t2 on t1.a=t2.a where t1.a not in (select t3.a from t3)", "Plan": [ "HashJoin 9990.00 root CARTESIAN anti semi join, other cond:eq(test.t1.a, test.t3.a)", - "├─TableReader(Build) 3.00 root data:TableFullScan", - "│ └─TableFullScan 3.00 cop[tikv] table:t3 keep order:false", + "├─IndexReader(Build) 3.00 root index:IndexFullScan", + "│ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", "└─HashJoin(Probe) 12487.50 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -7394,8 +7394,8 @@ "SQL": "select /*+ leading(t4) */ * from t1 join t2 on t1.a=t2.a join t4 on t1.b = t4.b where t1.a not in (select t3.a from t3)", "Plan": [ "HashJoin 12475.01 root CARTESIAN anti semi join, other cond:eq(test.t1.a, test.t3.a)", - "├─TableReader(Build) 3.00 root data:TableFullScan", - "│ └─TableFullScan 3.00 cop[tikv] table:t3 keep order:false", + "├─IndexReader(Build) 3.00 root index:IndexFullScan", + "│ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", "└─Projection(Probe) 15593.77 root test.t1.a, test.t1.b, test.t2.a, test.t2.b, test.t4.a, test.t4.b", " └─HashJoin 15593.77 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", @@ -7415,8 +7415,8 @@ "SQL": "select /*+ leading(t3@sel_2) */ * from t1 join t2 on t1.a=t2.a where t1.a not in (select t3.a from t3)", "Plan": [ "HashJoin 9990.00 root CARTESIAN anti semi join, other cond:eq(test.t1.a, test.t3.a)", - "├─TableReader(Build) 3.00 root data:TableFullScan", - "│ └─TableFullScan 3.00 cop[tikv] table:t3 keep order:false", + "├─IndexReader(Build) 3.00 root index:IndexFullScan", + "│ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", "└─HashJoin(Probe) 12487.50 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -7433,8 +7433,8 @@ "SQL": "select /*+ leading(t2, t3@sel_2) */ * from t1 join t2 on t1.a=t2.a where t1.a not in (select t3.a from t3)", "Plan": [ "HashJoin 9990.00 root CARTESIAN anti semi join, other cond:eq(test.t1.a, test.t3.a)", - "├─TableReader(Build) 3.00 root data:TableFullScan", - "│ └─TableFullScan 3.00 cop[tikv] table:t3 keep order:false", + "├─IndexReader(Build) 3.00 root index:IndexFullScan", + "│ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", "└─HashJoin(Probe) 12487.50 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -7452,8 +7452,8 @@ "SQL": "select /*+ leading(t1, t3@sel_2) */ * from t1 join t2 on t1.a=t2.a where t1.a not in (select t3.a from t3)", "Plan": [ "HashJoin 9990.00 root CARTESIAN anti semi join, other cond:eq(test.t1.a, test.t3.a)", - "├─TableReader(Build) 3.00 root data:TableFullScan", - "│ └─TableFullScan 3.00 cop[tikv] table:t3 keep order:false", + "├─IndexReader(Build) 3.00 root index:IndexFullScan", + "│ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", "└─HashJoin(Probe) 12487.50 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -7471,8 +7471,8 @@ "SQL": "select /*+ leading(t3@sel_2, t2) */ * from t1 join t2 on t1.a=t2.a where t1.a not in (select t3.a from t3)", "Plan": [ "HashJoin 9990.00 root CARTESIAN anti semi join, other cond:eq(test.t1.a, test.t3.a)", - "├─TableReader(Build) 3.00 root data:TableFullScan", - "│ └─TableFullScan 3.00 cop[tikv] table:t3 keep order:false", + "├─IndexReader(Build) 3.00 root index:IndexFullScan", + "│ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", "└─HashJoin(Probe) 12487.50 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))", @@ -7490,8 +7490,8 @@ "SQL": "select /*+ leading(t3@sel_2, t1) */ * from t1 join t2 on t1.a=t2.a where t1.a not in (select t3.a from t3)", "Plan": [ "HashJoin 9990.00 root CARTESIAN anti semi join, other cond:eq(test.t1.a, test.t3.a)", - "├─TableReader(Build) 3.00 root data:TableFullScan", - "│ └─TableFullScan 3.00 cop[tikv] table:t3 keep order:false", + "├─IndexReader(Build) 3.00 root index:IndexFullScan", + "│ └─IndexFullScan 3.00 cop[tikv] table:t3, index:a(a) keep order:false", "└─HashJoin(Probe) 12487.50 root inner join, equal:[eq(test.t1.a, test.t2.a)]", " ├─TableReader(Build) 9990.00 root data:Selection", " │ └─Selection 9990.00 cop[tikv] not(isnull(test.t2.a))",