Skip to content

Commit

Permalink
planner: support explain format='cost_trace' on model ver2 (#39840)
Browse files Browse the repository at this point in the history
ref #35240
  • Loading branch information
qw4990 authored Dec 13, 2022
1 parent 95cbc5f commit 2dea8dd
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 4 deletions.
28 changes: 28 additions & 0 deletions planner/core/cbo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,34 @@ func loadTableStats(fileName string, dom *domain.Domain) error {
return nil
}

func TestExplainCostTrace(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("create table t (a int)")
tk.MustExec("insert into t values (1)")

tk.MustExec("set tidb_cost_model_version=2")
tk.MustQuery("explain format='cost_trace' select * from t").Check(testkit.Rows(
`TableReader_5 10000.00 177906.67 ((scan(10000*logrowsize(32)*tikv_scan_factor(40.7))) + (net(10000*rowsize(16)*tidb_kv_net_factor(3.96))))/15.00 root data:TableFullScan_4`,
`└─TableFullScan_4 10000.00 2035000.00 scan(10000*logrowsize(32)*tikv_scan_factor(40.7)) cop[tikv] table:t keep order:false, stats:pseudo`))
tk.MustQuery("explain analyze format='cost_trace' select * from t").CheckAt([]int{0, 1, 2, 3, 4}, [][]interface{}{
{"TableReader_5", "10000.00", "177906.67", "((scan(10000*logrowsize(32)*tikv_scan_factor(40.7))) + (net(10000*rowsize(16)*tidb_kv_net_factor(3.96))))/15.00", "1"},
{"└─TableFullScan_4", "10000.00", "2035000.00", "scan(10000*logrowsize(32)*tikv_scan_factor(40.7))", "1"},
})

tk.MustExec("set tidb_cost_model_version=1")
tk.MustQuery("explain format='cost_trace' select * from t").Check(testkit.Rows(
// cost trace on model ver1 is not supported
`TableReader_5 10000.00 34418.00 N/A root data:TableFullScan_4`,
`└─TableFullScan_4 10000.00 435000.00 N/A cop[tikv] table:t keep order:false, stats:pseudo`,
))
tk.MustQuery("explain analyze format='cost_trace' select * from t").CheckAt([]int{0, 1, 2, 3, 4}, [][]interface{}{
{"TableReader_5", "10000.00", "34418.00", "N/A", "1"},
{"└─TableFullScan_4", "10000.00", "435000.00", "N/A", "1"},
})
}

func TestExplainAnalyze(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
Expand Down
28 changes: 24 additions & 4 deletions planner/core/common_plans.go
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,12 @@ func (e *Explain) prepareSchema() error {
}
case format == types.ExplainFormatTrueCardCost:
fieldNames = []string{"id", "estRows", "estCost", "costFormula", "actRows", "task", "access object", "execution info", "operator info", "memory", "disk"}
case format == types.ExplainFormatCostTrace:
if e.Analyze || e.RuntimeStatsColl != nil {
fieldNames = []string{"id", "estRows", "estCost", "costFormula", "actRows", "task", "access object", "execution info", "operator info", "memory", "disk"}
} else {
fieldNames = []string{"id", "estRows", "estCost", "costFormula", "task", "access object", "operator info"}
}
case (format == types.ExplainFormatROW || format == types.ExplainFormatBrief) && (e.Analyze || e.RuntimeStatsColl != nil):
fieldNames = []string{"id", "estRows", "actRows", "task", "access object", "execution info", "operator info", "memory", "disk"}
case format == types.ExplainFormatDOT:
Expand Down Expand Up @@ -813,8 +819,18 @@ func (e *Explain) RenderResult() error {
}
}

if strings.ToLower(e.Format) == types.ExplainFormatCostTrace {
if pp, ok := e.TargetPlan.(PhysicalPlan); ok {
// trigger getPlanCost again with CostFlagTrace to record all cost formulas
if _, err := getPlanCost(pp, property.RootTaskType,
NewDefaultPlanCostOption().WithCostFlag(CostFlagRecalculate|CostFlagTrace)); err != nil {
return err
}
}
}

switch strings.ToLower(e.Format) {
case types.ExplainFormatROW, types.ExplainFormatBrief, types.ExplainFormatVerbose, types.ExplainFormatTrueCardCost:
case types.ExplainFormatROW, types.ExplainFormatBrief, types.ExplainFormatVerbose, types.ExplainFormatTrueCardCost, types.ExplainFormatCostTrace:
if e.Rows == nil || e.Analyze {
flat := FlattenPhysicalPlan(e.TargetPlan, true)
e.explainFlatPlanInRowFormat(flat)
Expand Down Expand Up @@ -995,19 +1011,23 @@ func (e *Explain) prepareOperatorInfo(p Plan, taskType, id string) {
var row []string
if e.Analyze || e.RuntimeStatsColl != nil {
row = []string{id, estRows}
if strings.ToLower(e.Format) == types.ExplainFormatVerbose || strings.ToLower(e.Format) == types.ExplainFormatTrueCardCost {
if strings.ToLower(e.Format) == types.ExplainFormatVerbose || strings.ToLower(e.Format) == types.ExplainFormatTrueCardCost || strings.ToLower(e.Format) == types.ExplainFormatCostTrace {
row = append(row, estCost)
}
if strings.ToLower(e.Format) == types.ExplainFormatTrueCardCost {
if strings.ToLower(e.Format) == types.ExplainFormatTrueCardCost || strings.ToLower(e.Format) == types.ExplainFormatCostTrace {
row = append(row, costFormula)
}
actRows, analyzeInfo, memoryInfo, diskInfo := getRuntimeInfoStr(e.ctx, p, e.RuntimeStatsColl)
row = append(row, actRows, taskType, accessObject, analyzeInfo, operatorInfo, memoryInfo, diskInfo)
} else {
row = []string{id, estRows}
if strings.ToLower(e.Format) == types.ExplainFormatVerbose || strings.ToLower(e.Format) == types.ExplainFormatTrueCardCost {
if strings.ToLower(e.Format) == types.ExplainFormatVerbose || strings.ToLower(e.Format) == types.ExplainFormatTrueCardCost ||
strings.ToLower(e.Format) == types.ExplainFormatCostTrace {
row = append(row, estCost)
}
if strings.ToLower(e.Format) == types.ExplainFormatCostTrace {
row = append(row, costFormula)
}
row = append(row, taskType, accessObject, operatorInfo)
}
e.Rows = append(e.Rows, row)
Expand Down
3 changes: 3 additions & 0 deletions types/explain_format.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ var (
ExplainFormatBinary = "binary"
// ExplainFormatTiDBJSON warp the default result in JSON format
ExplainFormatTiDBJSON = "tidb_json"
// ExplainFormatCostTrace prints the cost and cost formula of each operator.
ExplainFormatCostTrace = "cost_trace"

// ExplainFormats stores the valid formats for explain statement, used by validator.
ExplainFormats = []string{
Expand All @@ -48,5 +50,6 @@ var (
ExplainFormatTrueCardCost,
ExplainFormatBinary,
ExplainFormatTiDBJSON,
ExplainFormatCostTrace,
}
)

0 comments on commit 2dea8dd

Please sign in to comment.