Commit 7b988e5c authored by Varun Gupta's avatar Varun Gupta

MDEV-20444: More information regarding access of a table to be printed inside the optimizer_trace

Added:
      1) estimated_join_cardinality
      2) best_chosen_access_method for a table
      3) best_join_order
parent e980cf91
This diff is collapsed.
...@@ -207,18 +207,29 @@ explain select * from t1 where a=1 or b=1 { ...@@ -207,18 +207,29 @@ explain select * from t1 where a=1 or b=1 {
"best_access_path": { "best_access_path": {
"considered_access_paths": [ "considered_access_paths": [
{ {
"access_type": "range", "access_type": "index_merge",
"resulting_rows": 2, "resulting_rows": 2,
"cost": 4.1484, "cost": 4.1484,
"chosen": true "chosen": true
} }
] ],
"chosen_access_method": {
"type": "index_merge",
"records": 2,
"cost": 4.1484,
"uses_join_buffering": false,
"filter_used": false
}
}, },
"rows_for_plan": 2, "rows_for_plan": 2,
"cost_for_plan": 4.5484 "cost_for_plan": 4.5484,
"estimated_join_cardinality": 2
} }
] ]
}, },
{
"best_join_order": ["t1"]
},
{ {
"attaching_conditions_to_tables": { "attaching_conditions_to_tables": {
"original_condition": "t1.a = 1 or t1.b = 1", "original_condition": "t1.a = 1 or t1.b = 1",
......
...@@ -208,13 +208,24 @@ explain select * from t1 where pk1 != 0 and key1 = 1 { ...@@ -208,13 +208,24 @@ explain select * from t1 where pk1 != 0 and key1 = 1 {
"chosen": false, "chosen": false,
"cause": "cost" "cause": "cost"
} }
] ],
"chosen_access_method": {
"type": "ref",
"records": 1,
"cost": 2,
"uses_join_buffering": false,
"filter_used": false
}
}, },
"rows_for_plan": 1, "rows_for_plan": 1,
"cost_for_plan": 2.2 "cost_for_plan": 2.2,
"estimated_join_cardinality": 1
} }
] ]
}, },
{
"best_join_order": ["t1"]
},
{ {
"attaching_conditions_to_tables": { "attaching_conditions_to_tables": {
"original_condition": "t1.key1 = 1 and t1.pk1 <> 0", "original_condition": "t1.key1 = 1 and t1.pk1 <> 0",
......
...@@ -98,13 +98,24 @@ select * from db1.t1 { ...@@ -98,13 +98,24 @@ select * from db1.t1 {
"cost": 2.0051, "cost": 2.0051,
"chosen": true "chosen": true
} }
] ],
"chosen_access_method": {
"type": "scan",
"records": 3,
"cost": 2.0051,
"uses_join_buffering": false,
"filter_used": false
}
}, },
"rows_for_plan": 3, "rows_for_plan": 3,
"cost_for_plan": 2.6051 "cost_for_plan": 2.6051,
"estimated_join_cardinality": 3
} }
] ]
}, },
{
"best_join_order": ["t1"]
},
{ {
"attaching_conditions_to_tables": { "attaching_conditions_to_tables": {
"original_condition": null, "original_condition": null,
...@@ -211,13 +222,24 @@ select * from db1.v1 { ...@@ -211,13 +222,24 @@ select * from db1.v1 {
"cost": 2.0051, "cost": 2.0051,
"chosen": true "chosen": true
} }
] ],
"chosen_access_method": {
"type": "scan",
"records": 3,
"cost": 2.0051,
"uses_join_buffering": false,
"filter_used": false
}
}, },
"rows_for_plan": 3, "rows_for_plan": 3,
"cost_for_plan": 2.6051 "cost_for_plan": 2.6051,
"estimated_join_cardinality": 3
} }
] ]
}, },
{
"best_join_order": ["t1"]
},
{ {
"attaching_conditions_to_tables": { "attaching_conditions_to_tables": {
"original_condition": null, "original_condition": null,
......
...@@ -630,6 +630,45 @@ void add_table_scan_values_to_trace(THD *thd, JOIN_TAB *tab) ...@@ -630,6 +630,45 @@ void add_table_scan_values_to_trace(THD *thd, JOIN_TAB *tab)
table_rec.add("rows", tab->found_records) table_rec.add("rows", tab->found_records)
.add("cost", tab->read_time); .add("cost", tab->read_time);
} }
/*
Print the join order of all the tables for top level select.
For example:
select * from ot1
where ot1.a IN (select it1.a from it1, it2 where it1.b=it2.a);
So this function would print
ot1, <subquery2> ----> For select #1
*/
void print_final_join_order(JOIN *join)
{
Json_writer_object join_order(join->thd);
Json_writer_array best_order(join->thd, "best_join_order");
JOIN_TAB *j;
uint i;
for (j= join->join_tab,i=0 ; i < join->top_join_tab_count;
i++, j++)
best_order.add_table_name(j);
}
void print_best_access_for_table(THD *thd, POSITION *pos,
enum join_type type)
{
Json_writer_object trace_best_access(thd, "chosen_access_method");
trace_best_access.add("type", type == JT_ALL ? "scan" :
join_type_str[type]);
trace_best_access.add("records", pos->records_read);
trace_best_access.add("cost", pos->read_time);
trace_best_access.add("uses_join_buffering", pos->use_join_buffer);
trace_best_access.add("filter_used",
pos->range_rowid_filter_info != NULL);
}
/* /*
Introduce enum_query_type flags parameter, maybe also allow Introduce enum_query_type flags parameter, maybe also allow
EXPLAIN also use this function. EXPLAIN also use this function.
......
...@@ -105,6 +105,9 @@ void opt_trace_print_expanded_query(THD *thd, SELECT_LEX *select_lex, ...@@ -105,6 +105,9 @@ void opt_trace_print_expanded_query(THD *thd, SELECT_LEX *select_lex,
Json_writer_object *trace_object); Json_writer_object *trace_object);
void add_table_scan_values_to_trace(THD *thd, JOIN_TAB *tab); void add_table_scan_values_to_trace(THD *thd, JOIN_TAB *tab);
void print_final_join_order(JOIN *join);
void print_best_access_for_table(THD *thd, POSITION *pos,
enum join_type type);
/* /*
Security related (need to add a proper comment here) Security related (need to add a proper comment here)
......
...@@ -7203,6 +7203,7 @@ best_access_path(JOIN *join, ...@@ -7203,6 +7203,7 @@ best_access_path(JOIN *join,
SplM_plan_info *spl_plan= 0; SplM_plan_info *spl_plan= 0;
Range_rowid_filter_cost_info *filter= 0; Range_rowid_filter_cost_info *filter= 0;
const char* cause= NULL; const char* cause= NULL;
enum join_type best_type= JT_UNKNOWN, type= JT_UNKNOWN;
disable_jbuf= disable_jbuf || idx == join->const_tables; disable_jbuf= disable_jbuf || idx == join->const_tables;
...@@ -7342,7 +7343,8 @@ best_access_path(JOIN *join, ...@@ -7342,7 +7343,8 @@ best_access_path(JOIN *join,
*/ */
tmp= prev_record_reads(join->positions, idx, found_ref); tmp= prev_record_reads(join->positions, idx, found_ref);
records= 1.0; records= 1.0;
trace_access_idx.add("access_type", "fulltext") type= JT_FT;
trace_access_idx.add("access_type", join_type_str[type])
.add("index", keyinfo->name); .add("index", keyinfo->name);
} }
else else
...@@ -7365,14 +7367,16 @@ best_access_path(JOIN *join, ...@@ -7365,14 +7367,16 @@ best_access_path(JOIN *join,
(!(key_flags & HA_NULL_PART_KEY) || // (2) (!(key_flags & HA_NULL_PART_KEY) || // (2)
all_key_parts == notnull_part)) // (3) all_key_parts == notnull_part)) // (3)
{ {
trace_access_idx.add("access_type", "eq_ref") type= JT_EQ_REF;
trace_access_idx.add("access_type", join_type_str[type])
.add("index", keyinfo->name); .add("index", keyinfo->name);
tmp = prev_record_reads(join->positions, idx, found_ref); tmp = prev_record_reads(join->positions, idx, found_ref);
records=1.0; records=1.0;
} }
else else
{ {
trace_access_idx.add("access_type", "ref") type= JT_REF;
trace_access_idx.add("access_type", join_type_str[type])
.add("index", keyinfo->name); .add("index", keyinfo->name);
if (!found_ref) if (!found_ref)
{ /* We found a const key */ { /* We found a const key */
...@@ -7467,8 +7471,8 @@ best_access_path(JOIN *join, ...@@ -7467,8 +7471,8 @@ best_access_path(JOIN *join,
} }
else else
{ {
trace_access_idx.add("access_type", type = ref_or_null_part ? JT_REF_OR_NULL : JT_REF;
ref_or_null_part ? "ref_or_null" : "ref") trace_access_idx.add("access_type", join_type_str[type])
.add("index", keyinfo->name); .add("index", keyinfo->name);
/* /*
Use as much key-parts as possible and a uniq key is better Use as much key-parts as possible and a uniq key is better
...@@ -7683,6 +7687,7 @@ best_access_path(JOIN *join, ...@@ -7683,6 +7687,7 @@ best_access_path(JOIN *join,
best_max_key_part= max_key_part; best_max_key_part= max_key_part;
best_ref_depends_map= found_ref; best_ref_depends_map= found_ref;
best_filter= filter; best_filter= filter;
best_type= type;
} }
else else
{ {
...@@ -7736,6 +7741,7 @@ best_access_path(JOIN *join, ...@@ -7736,6 +7741,7 @@ best_access_path(JOIN *join,
best_ref_depends_map= 0; best_ref_depends_map= 0;
best_uses_jbuf= TRUE; best_uses_jbuf= TRUE;
best_filter= 0; best_filter= 0;
best_type= JT_HASH;
trace_access_hash.add("type", "hash"); trace_access_hash.add("type", "hash");
trace_access_hash.add("index", "hj-key"); trace_access_hash.add("index", "hj-key");
trace_access_hash.add("cost", rnd_records); trace_access_hash.add("cost", rnd_records);
...@@ -7799,10 +7805,6 @@ best_access_path(JOIN *join, ...@@ -7799,10 +7805,6 @@ best_access_path(JOIN *join,
filter= 0; filter= 0;
if (s->quick) if (s->quick)
{ {
trace_access_scan.add("access_type", "range");
/*
should have some info about all the different QUICK_SELECT
*/
/* /*
For each record we: For each record we:
- read record range through 'quick' - read record range through 'quick'
...@@ -7828,23 +7830,29 @@ best_access_path(JOIN *join, ...@@ -7828,23 +7830,29 @@ best_access_path(JOIN *join,
{ {
tmp-= filter->get_adjusted_gain(rows); tmp-= filter->get_adjusted_gain(rows);
DBUG_ASSERT(tmp >= 0); DBUG_ASSERT(tmp >= 0);
} }
type= JT_RANGE;
} }
else else
{ {
type= JT_INDEX_MERGE;
best_filter= 0; best_filter= 0;
} }
loose_scan_opt.check_range_access(join, idx, s->quick); loose_scan_opt.check_range_access(join, idx, s->quick);
} }
else else
{ {
trace_access_scan.add("access_type", "scan");
/* Estimate cost of reading table. */ /* Estimate cost of reading table. */
if (s->table->force_index && !best_key) // index scan if (s->table->force_index && !best_key) // index scan
{
type= JT_NEXT;
tmp= s->table->file->read_time(s->ref.key, 1, s->records); tmp= s->table->file->read_time(s->ref.key, 1, s->records);
}
else // table scan else // table scan
{
tmp= s->scan_time(); tmp= s->scan_time();
type= JT_ALL;
}
if ((s->table->map & join->outer_join) || disable_jbuf) // Can't use join cache if ((s->table->map & join->outer_join) || disable_jbuf) // Can't use join cache
{ {
...@@ -7874,6 +7882,9 @@ best_access_path(JOIN *join, ...@@ -7874,6 +7882,9 @@ best_access_path(JOIN *join,
} }
} }
trace_access_scan.add("access_type", type == JT_ALL ?
"scan" :
join_type_str[type]);
/* Splitting technique cannot be used with join cache */ /* Splitting technique cannot be used with join cache */
if (s->table->is_splittable()) if (s->table->is_splittable())
tmp+= s->table->get_materialization_cost(); tmp+= s->table->get_materialization_cost();
...@@ -7913,6 +7924,7 @@ best_access_path(JOIN *join, ...@@ -7913,6 +7924,7 @@ best_access_path(JOIN *join,
best_uses_jbuf= MY_TEST(!disable_jbuf && !((s->table->map & best_uses_jbuf= MY_TEST(!disable_jbuf && !((s->table->map &
join->outer_join))); join->outer_join)));
spl_plan= 0; spl_plan= 0;
best_type= type;
} }
trace_access_scan.add("chosen", best_key == NULL); trace_access_scan.add("chosen", best_key == NULL);
} }
...@@ -7944,6 +7956,11 @@ best_access_path(JOIN *join, ...@@ -7944,6 +7956,11 @@ best_access_path(JOIN *join,
trace_access_scan.add("use_tmp_table", true); trace_access_scan.add("use_tmp_table", true);
join->sort_by_table= (TABLE*) 1; // Must use temporary table join->sort_by_table= (TABLE*) 1; // Must use temporary table
} }
trace_access_scan.end();
trace_paths.end();
if (unlikely(thd->trace_started()))
print_best_access_for_table(thd, pos, best_type);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -9484,6 +9501,8 @@ best_extension_by_limited_search(JOIN *join, ...@@ -9484,6 +9501,8 @@ best_extension_by_limited_search(JOIN *join,
Hence it may be wrong. Hence it may be wrong.
*/ */
current_read_time= COST_ADD(current_read_time, current_record_count); current_read_time= COST_ADD(current_read_time, current_record_count);
trace_one_table.add("estimated_join_cardinality",
partial_join_cardinality);
if (current_read_time < join->best_read) if (current_read_time < join->best_read)
{ {
memcpy((uchar*) join->best_positions, (uchar*) join->positions, memcpy((uchar*) join->best_positions, (uchar*) join->positions,
...@@ -10305,6 +10324,9 @@ bool JOIN::get_best_combination() ...@@ -10305,6 +10324,9 @@ bool JOIN::get_best_combination()
top_join_tab_count= (uint)(join_tab_ranges.head()->end - top_join_tab_count= (uint)(join_tab_ranges.head()->end -
join_tab_ranges.head()->start); join_tab_ranges.head()->start);
if (unlikely(thd->trace_started()))
print_final_join_order(this);
update_depend_map(this); update_depend_map(this);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment