Make trace.add() usage uniform

- Before any multiple add() calls, always use (if trace_started()).
- Add unlikely() around all tests of trace_started().
- Change trace.add(); trace.add(); to trace.add().add();
- When trace.add() goes over several line, use the following formating:
trace.
 add(xxx).
 add(yyy).
 add(zzz);

This format was choosen after a discussion between Sergei Petrunia and
me as it looks similar indepedent if 'trace' is an object or a
pointer. It also more suitable for an editors auto-indentation.

Other things:

Added DBUG_ASSERT(thd->trace_started()) to a few functions that should
only be called if trace is enabled.

"use_roworder_index_merge: true" changed to "use_sort_index_merge: false"
As the original output was often not correct.
Also fixed the related 'cause' to be correct.

In best_access_path() print the cost (and number of rows) before
checking if it the plan should be used. This removes the need to print
the cost in two places.

Changed a few "read_time" tags to "cost".
This commit is contained in:
Monty 2022-01-20 15:49:01 +02:00 committed by Sergei Petrunia
parent ec6aa2829a
commit 766bae2b31
11 changed files with 429 additions and 250 deletions

View File

@ -1117,6 +1117,7 @@ explain select * from t1,t2 where t1.a=t2.b+2 and t2.a= t1.b {
"rows": 1, "rows": 1,
"cond_check_cost": 2.200585794, "cond_check_cost": 2.200585794,
"startup_cost": 0, "startup_cost": 0,
"rows_after_filter": 1,
"cost": 220.0585794, "cost": 220.0585794,
"chosen": true "chosen": true
}, },
@ -1166,6 +1167,7 @@ explain select * from t1,t2 where t1.a=t2.b+2 and t2.a= t1.b {
"rows": 1, "rows": 1,
"cond_check_cost": 2.200585794, "cond_check_cost": 2.200585794,
"startup_cost": 0, "startup_cost": 0,
"rows_after_filter": 1,
"cost": 220.0585794, "cost": 220.0585794,
"chosen": true "chosen": true
}, },
@ -2265,6 +2267,7 @@ explain select * from t1 where a=1 and b=2 order by c limit 1 {
"rows": 180, "rows": 180,
"cond_check_cost": 216.2743776, "cond_check_cost": 216.2743776,
"startup_cost": 0, "startup_cost": 0,
"rows_after_filter": 180,
"cost": 216.2743776, "cost": 216.2743776,
"chosen": true "chosen": true
}, },
@ -2275,6 +2278,7 @@ explain select * from t1 where a=1 and b=2 order by c limit 1 {
"rows": 21, "rows": 21,
"cond_check_cost": 25.34242739, "cond_check_cost": 25.34242739,
"startup_cost": 0, "startup_cost": 0,
"rows_after_filter": 21,
"cost": 25.34242739, "cost": 25.34242739,
"chosen": true "chosen": true
}, },
@ -2724,6 +2728,7 @@ explain select * from t1 left join t2 on t2.a=t1.a {
"rows": 1, "rows": 1,
"cond_check_cost": 1.2, "cond_check_cost": 1.2,
"startup_cost": 0, "startup_cost": 0,
"rows_after_filter": 1,
"cost": 4.8, "cost": 4.8,
"chosen": true "chosen": true
}, },
@ -3253,7 +3258,7 @@ explain extended select * from t1 where a in (select pk from t10) {
{ {
"strategy": "SJ-Materialization", "strategy": "SJ-Materialization",
"records": 3, "records": 3,
"read_time": 7.878564453 "cost": 7.878564453
}, },
{ {
"strategy": "DuplicateWeedout", "strategy": "DuplicateWeedout",
@ -3628,6 +3633,7 @@ explain select * from t1 where pk = 2 and a=5 and b=1 {
"rows": 1, "rows": 1,
"cond_check_cost": 1.325585794, "cond_check_cost": 1.325585794,
"startup_cost": 0, "startup_cost": 0,
"rows_after_filter": 1,
"cost": 1.325585794, "cost": 1.325585794,
"chosen": true "chosen": true
}, },
@ -3638,6 +3644,7 @@ explain select * from t1 where pk = 2 and a=5 and b=1 {
"rows": 1, "rows": 1,
"cond_check_cost": 1.325829876, "cond_check_cost": 1.325829876,
"startup_cost": 0, "startup_cost": 0,
"rows_after_filter": 1,
"cost": 1.325829876, "cost": 1.325829876,
"chosen": false, "chosen": false,
"cause": "cost" "cause": "cost"
@ -3649,6 +3656,7 @@ explain select * from t1 where pk = 2 and a=5 and b=1 {
"rows": 1, "rows": 1,
"cond_check_cost": 0.326073957, "cond_check_cost": 0.326073957,
"startup_cost": 0, "startup_cost": 0,
"rows_after_filter": 1,
"cost": 0.326073957, "cost": 0.326073957,
"chosen": true "chosen": true
}, },
@ -4341,6 +4349,7 @@ explain delete t0,t1 from t0, t1 where t0.a=t1.a and t1.a<3 {
"rows": 1, "rows": 1,
"cond_check_cost": 1.200585794, "cond_check_cost": 1.200585794,
"startup_cost": 0, "startup_cost": 0,
"rows_after_filter": 1,
"cost": 3.601757383, "cost": 3.601757383,
"chosen": true "chosen": true
}, },
@ -4390,6 +4399,7 @@ explain delete t0,t1 from t0, t1 where t0.a=t1.a and t1.a<3 {
"rows": 2, "rows": 2,
"cond_check_cost": 1.401171589, "cond_check_cost": 1.401171589,
"startup_cost": 0, "startup_cost": 0,
"rows_after_filter": 2,
"cost": 4.203514767, "cost": 4.203514767,
"chosen": true "chosen": true
}, },
@ -5080,7 +5090,7 @@ explain select * from t1 where a in (select t_inner_1.a from t1 t_inner_1, t1 t_
{ {
"strategy": "SJ-Materialization", "strategy": "SJ-Materialization",
"records": 3, "records": 3,
"read_time": 10.81538086 "cost": 10.81538086
}, },
{ {
"strategy": "DuplicateWeedout", "strategy": "DuplicateWeedout",
@ -7976,7 +7986,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) {
{ {
"strategy": "SJ-Materialization", "strategy": "SJ-Materialization",
"records": 27, "records": 27,
"read_time": 32.34101562 "cost": 32.34101562
}, },
{ {
"strategy": "DuplicateWeedout", "strategy": "DuplicateWeedout",
@ -8098,7 +8108,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) {
{ {
"strategy": "SJ-Materialization", "strategy": "SJ-Materialization",
"records": 27, "records": 27,
"read_time": 46.86152344 "cost": 46.86152344
}, },
{ {
"strategy": "DuplicateWeedout", "strategy": "DuplicateWeedout",
@ -8395,7 +8405,7 @@ t_outer_2.a in (select t_inner_3.a from t2 t_inner_3, t1 t_inner_4) {
{ {
"strategy": "SJ-Materialization", "strategy": "SJ-Materialization",
"records": 3, "records": 3,
"read_time": 16.52563477 "cost": 16.52563477
}, },
{ {
"strategy": "DuplicateWeedout", "strategy": "DuplicateWeedout",
@ -9539,6 +9549,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans'))
"rows": 1, "rows": 1,
"cond_check_cost": 2.200585794, "cond_check_cost": 2.200585794,
"startup_cost": 0, "startup_cost": 0,
"rows_after_filter": 1,
"cost": 22.00585794, "cost": 22.00585794,
"chosen": true "chosen": true
}, },
@ -9769,6 +9780,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans'))
"rows": 1, "rows": 1,
"cond_check_cost": 2.200585794, "cond_check_cost": 2.200585794,
"startup_cost": 0, "startup_cost": 0,
"rows_after_filter": 1,
"cost": 22.00585794, "cost": 22.00585794,
"chosen": true "chosen": true
}, },
@ -10408,6 +10420,7 @@ json_detailed(json_extract(trace, '$**.choose_best_splitting'))
"rows": 1.8367, "rows": 1.8367,
"cond_check_cost": 2.367925794, "cond_check_cost": 2.367925794,
"startup_cost": 0, "startup_cost": 0,
"rows_after_filter": 1.8367,
"cost": 2.367925794, "cost": 2.367925794,
"chosen": true "chosen": true
}, },

View File

@ -214,6 +214,7 @@ explain select * from t1 where pk1 != 0 and key1 = 1 {
"rows": 1, "rows": 1,
"cond_check_cost": 1.325146475, "cond_check_cost": 1.325146475,
"startup_cost": 0, "startup_cost": 0,
"rows_after_filter": 1,
"cost": 1.325146475, "cost": 1.325146475,
"chosen": true "chosen": true
}, },

View File

@ -51,6 +51,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans'))
"rows": 104, "rows": 104,
"cond_check_cost": 124.96562, "cond_check_cost": 124.96562,
"startup_cost": 0, "startup_cost": 0,
"rows_after_filter": 104,
"cost": 124.96562, "cost": 124.96562,
"chosen": true "chosen": true
}, },
@ -61,6 +62,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans'))
"rows": 340, "rows": 340,
"cond_check_cost": 408.2577963, "cond_check_cost": 408.2577963,
"startup_cost": 0, "startup_cost": 0,
"rows_after_filter": 340,
"cost": 408.2577963, "cost": 408.2577963,
"chosen": false, "chosen": false,
"cause": "cost" "cause": "cost"
@ -72,6 +74,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans'))
"rows": 632, "rows": 632,
"cond_check_cost": 758.7718449, "cond_check_cost": 758.7718449,
"startup_cost": 0, "startup_cost": 0,
"rows_after_filter": 632,
"cost": 758.7718449, "cost": 758.7718449,
"chosen": false, "chosen": false,
"cause": "cost" "cause": "cost"
@ -145,6 +148,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans'))
"rows": 6, "rows": 6,
"cond_check_cost": 7.327343464, "cond_check_cost": 7.327343464,
"startup_cost": 0, "startup_cost": 0,
"rows_after_filter": 6,
"cost": 7.327343464, "cost": 7.327343464,
"chosen": true "chosen": true
}, },
@ -155,6 +159,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans'))
"rows": 232, "rows": 232,
"cond_check_cost": 278.6156139, "cond_check_cost": 278.6156139,
"startup_cost": 0, "startup_cost": 0,
"rows_after_filter": 232,
"cost": 278.6156139, "cost": 278.6156139,
"chosen": false, "chosen": false,
"cause": "cost" "cause": "cost"
@ -166,6 +171,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans'))
"rows": 293, "rows": 293,
"cond_check_cost": 351.8394392, "cond_check_cost": 351.8394392,
"startup_cost": 0, "startup_cost": 0,
"rows_after_filter": 293,
"cost": 351.8394392, "cost": 351.8394392,
"chosen": false, "chosen": false,
"cause": "cost" "cause": "cost"

View File

@ -2294,9 +2294,11 @@ void TRP_RANGE::trace_basic_info(PARAM *param,
const KEY &cur_key= param->table->key_info[keynr_in_table]; const KEY &cur_key= param->table->key_info[keynr_in_table];
const KEY_PART_INFO *key_part= cur_key.key_part; const KEY_PART_INFO *key_part= cur_key.key_part;
trace_object->add("type", "range_scan") if (unlikely(trace_object->trace_started()))
.add("index", cur_key.name) trace_object->
.add("rows", records); add("type", "range_scan").
add("index", cur_key.name).
add("rows", records);
Json_writer_array trace_range(param->thd, "ranges"); Json_writer_array trace_range(param->thd, "ranges");
@ -2500,11 +2502,13 @@ void TRP_GROUP_MIN_MAX::trace_basic_info(PARAM *param,
else else
trace_object->add_null("min_max_arg"); trace_object->add_null("min_max_arg");
trace_object->add("min_aggregate", have_min) if (unlikely(trace_object->trace_started()))
.add("max_aggregate", have_max) trace_object->
.add("distinct_aggregate", have_agg_distinct) add("min_aggregate", have_min).
.add("rows", records) add("max_aggregate", have_max).
.add("cost", read_cost); add("distinct_aggregate", have_agg_distinct).
add("rows", records).
add("cost", read_cost);
const KEY_PART_INFO *key_part= index_info->key_part; const KEY_PART_INFO *key_part= index_info->key_part;
{ {
@ -2734,6 +2738,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
table_info.add_table_name(head); table_info.add_table_name(head);
Json_writer_object trace_range(thd, "range_analysis"); Json_writer_object trace_range(thd, "range_analysis");
if (unlikely(thd->trace_started()))
{ {
Json_writer_object table_rec(thd, "table_scan"); Json_writer_object table_rec(thd, "table_scan");
table_rec.add("rows", records).add("cost", read_time); table_rec.add("rows", records).add("cost", read_time);
@ -2807,8 +2812,10 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
if (!keys_to_use.is_set(idx)) if (!keys_to_use.is_set(idx))
{ {
trace_idx_details.add("usable", false) if (unlikely(trace_idx_details.trace_started()))
.add("cause", "not applicable"); trace_idx_details.
add("usable", false).
add("cause", "not applicable");
continue; continue;
} }
if (key_info->flags & HA_FULLTEXT) if (key_info->flags & HA_FULLTEXT)
@ -2873,10 +2880,14 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
read_time= key_read_time; read_time= key_read_time;
chosen= TRUE; chosen= TRUE;
} }
trace_cov.add("index", head->key_info[key_for_use].name) if (unlikely(trace_cov.trace_started()))
.add("cost", key_read_time).add("chosen", chosen); {
if (!chosen) trace_cov.
trace_cov.add("cause", "cost"); add("index", head->key_info[key_for_use].name).
add("cost", key_read_time).add("chosen", chosen);
if (!chosen)
trace_cov.add("cause", "cost");
}
} }
double best_read_time= read_time; double best_read_time= read_time;
@ -3091,9 +3102,10 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
Json_writer_object trace_range_plan(thd, "range_access_plan"); Json_writer_object trace_range_plan(thd, "range_access_plan");
best_trp->trace_basic_info(&param, &trace_range_plan); best_trp->trace_basic_info(&param, &trace_range_plan);
} }
trace_range_summary.add("rows_for_plan", quick->records) trace_range_summary.
.add("cost_for_plan", quick->read_time) add("rows_for_plan", quick->records).
.add("chosen", true); add("cost_for_plan", quick->read_time).
add("chosen", true);
} }
free_root(&alloc,MYF(0)); // Return memory & allocator free_root(&alloc,MYF(0)); // Return memory & allocator
@ -3507,11 +3519,12 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item **cond)
*/ */
table->multiply_cond_selectivity(quick_cond_selectivity); table->multiply_cond_selectivity(quick_cond_selectivity);
if (unlikely(thd->trace_started()))
{ {
Json_writer_object selectivity_for_index(thd); Json_writer_object selectivity_for_index(thd);
selectivity_for_index.add("index_name", key_info->name) selectivity_for_index.
.add("selectivity_from_index", add("index_name", key_info->name).
quick_cond_selectivity); add("selectivity_from_index", quick_cond_selectivity);
} }
/* /*
We need to set selectivity for fields supported by indexes. We need to set selectivity for fields supported by indexes.
@ -3549,10 +3562,13 @@ end_of_range_loop:
quick->get_type() == QUICK_SELECT_I::QS_TYPE_ROR_UNION || quick->get_type() == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
quick->get_type() == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE || quick->get_type() == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
quick->get_type() == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT)); quick->get_type() == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT));
Json_writer_object selectivity_for_index(thd);
table->cond_selectivity= original_selectivity; table->cond_selectivity= original_selectivity;
selectivity_for_index.add("use_opt_range_condition_rows_selectivity", if (unlikely(thd->trace_started()))
original_selectivity); {
Json_writer_object selectivity_for_index(thd);
selectivity_for_index.add("use_opt_range_condition_rows_selectivity",
original_selectivity);
}
} }
selectivity_for_indexes.end(); selectivity_for_indexes.end();
@ -3625,8 +3641,10 @@ end_of_range_loop:
{ {
rows= 0; rows= 0;
table->reginfo.impossible_range= 1; table->reginfo.impossible_range= 1;
selectivity_for_column.add("selectivity_from_histogram", rows); if (unlikely(selectivity_for_column.trace_started()))
selectivity_for_column.add("cause", "impossible range"); selectivity_for_column.
add("selectivity_from_histogram", rows).
add("cause", "impossible range");
goto free_alloc; goto free_alloc;
} }
else else
@ -5269,9 +5287,10 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
} }
else else
non_cpk_scan_records += (*cur_child)->records; non_cpk_scan_records += (*cur_child)->records;
trace_idx.add("index_to_merge", if (unlikely(trace_idx.trace_started()))
param->table->key_info[keynr_in_table].name) trace_idx.
.add("cumulated_cost", imerge_cost); add("index_to_merge", param->table->key_info[keynr_in_table].name).
add("cumulated_cost", imerge_cost);
} }
to_merge.end(); to_merge.end();
@ -5303,9 +5322,10 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
optimizer_flag(param->thd, OPTIMIZER_SWITCH_INDEX_MERGE_UNION)) optimizer_flag(param->thd, OPTIMIZER_SWITCH_INDEX_MERGE_UNION))
{ {
roru_read_plans= (TABLE_READ_PLAN**)range_scans; roru_read_plans= (TABLE_READ_PLAN**)range_scans;
trace_best_disjunct.add("use_roworder_union", true) if (unlikely(trace_best_disjunct.trace_started()))
.add("cause", trace_best_disjunct.
"always cheaper than non roworder retrieval"); add("use_roworder_union", true).
add("cause", "always cheaper than non roworder retrieval");
goto skip_to_ror_scan; goto skip_to_ror_scan;
} }
@ -5326,16 +5346,21 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
{ {
double sweep_cost= get_sweep_read_cost(param, non_cpk_scan_records); double sweep_cost= get_sweep_read_cost(param, non_cpk_scan_records);
imerge_cost+= sweep_cost; imerge_cost+= sweep_cost;
trace_best_disjunct.add("cost_sort_rowid_and_read_disk", sweep_cost); trace_best_disjunct.
add("records", non_cpk_scan_records).
add("cost_sort_rowid_and_read_disk", sweep_cost).
add("cost", imerge_cost);
} }
DBUG_PRINT("info",("index_merge cost with rowid-to-row scan: %g", DBUG_PRINT("info",("index_merge cost with rowid-to-row scan: %g",
imerge_cost)); imerge_cost));
if (imerge_cost > read_time || if (imerge_cost > read_time ||
!optimizer_flag(param->thd, OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION)) !optimizer_flag(param->thd, OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION))
{ {
trace_best_disjunct.add("use_roworder_index_merge", true); if (unlikely(trace_best_disjunct.trace_started()))
trace_best_disjunct.add("cause", "cost"); trace_best_disjunct.
goto build_ror_index_merge; add("use_sort_index_merge", false).
add("cause", imerge_cost > read_time ? "cost" : "disabled");
goto build_ror_index_merge; // Try roworder_index_merge
} }
/* Add Unique operations cost */ /* Add Unique operations cost */
@ -5359,8 +5384,10 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
TIME_FOR_COMPARE_ROWID, TIME_FOR_COMPARE_ROWID,
FALSE, NULL); FALSE, NULL);
imerge_cost+= dup_removal_cost; imerge_cost+= dup_removal_cost;
trace_best_disjunct.add("cost_duplicate_removal", dup_removal_cost) if (unlikely(trace_best_disjunct.trace_started()))
.add("total_cost", imerge_cost); trace_best_disjunct.
add("cost_duplicate_removal", dup_removal_cost).
add("total_cost", imerge_cost);
} }
DBUG_PRINT("info",("index_merge total cost: %g (wanted: less then %g)", DBUG_PRINT("info",("index_merge total cost: %g (wanted: less then %g)",
@ -5476,8 +5503,10 @@ skip_to_ror_scan:
DBUG_PRINT("info", ("ROR-union: cost %g, %zu members", DBUG_PRINT("info", ("ROR-union: cost %g, %zu members",
roru_total_cost, n_child_scans)); roru_total_cost, n_child_scans));
trace_best_disjunct.add("index_roworder_union_cost", roru_total_cost) if (unlikely(trace_best_disjunct.trace_started()))
.add("members", n_child_scans); trace_best_disjunct.
add("index_roworder_union_cost", roru_total_cost).
add("members", n_child_scans);
TRP_ROR_UNION* roru; TRP_ROR_UNION* roru;
if (roru_total_cost < read_time) if (roru_total_cost < read_time)
{ {
@ -5880,15 +5909,19 @@ bool prepare_search_best_index_intersect(PARAM *param,
if (*index_scan == cpk_scan) if (*index_scan == cpk_scan)
{ {
idx_scan.add("chosen", "false") if (unlikely(idx_scan.trace_started()))
.add("cause", "clustered index used for filtering"); idx_scan.
add("chosen", "false").
add("cause", "clustered index used for filtering");
continue; continue;
} }
if (cpk_scan && cpk_scan->used_key_parts >= used_key_parts && if (cpk_scan && cpk_scan->used_key_parts >= used_key_parts &&
same_index_prefix(cpk_scan->key_info, key_info, used_key_parts)) same_index_prefix(cpk_scan->key_info, key_info, used_key_parts))
{ {
idx_scan.add("chosen", "false") if (unlikely(idx_scan.trace_started()))
.add("cause", "clustered index used for filtering"); idx_scan.
add("chosen", "false").
add("cause", "clustered index used for filtering");
continue; continue;
} }
@ -5898,8 +5931,8 @@ bool prepare_search_best_index_intersect(PARAM *param,
if (cost >= cutoff_cost) if (cost >= cutoff_cost)
{ {
idx_scan.add("chosen", false); if (unlikely(idx_scan.trace_started()))
idx_scan.add("cause", "cost"); idx_scan.add("chosen", false).add("cause", "cost");
continue; continue;
} }
@ -5918,15 +5951,18 @@ bool prepare_search_best_index_intersect(PARAM *param,
} }
if (!*scan_ptr || cost < (*scan_ptr)->index_read_cost) if (!*scan_ptr || cost < (*scan_ptr)->index_read_cost)
{ {
idx_scan.add("chosen", true); if (unlikely(idx_scan.trace_started()))
if (!*scan_ptr) {
idx_scan.add("cause", "first occurrence of index prefix"); idx_scan.add("chosen", true);
else if (!*scan_ptr)
idx_scan.add("cause", "better cost for same idx prefix"); idx_scan.add("cause", "first occurrence of index prefix");
else
idx_scan.add("cause", "better cost for same idx prefix");
}
*scan_ptr= *index_scan; *scan_ptr= *index_scan;
(*scan_ptr)->index_read_cost= cost; (*scan_ptr)->index_read_cost= cost;
} }
else else if (unlikely(idx_scan.trace_started()))
{ {
idx_scan.add("chosen", false).add("cause", "cost"); idx_scan.add("chosen", false).add("cause", "cost");
} }
@ -5989,13 +6025,14 @@ bool prepare_search_best_index_intersect(PARAM *param,
ha_rows records= records_in_index_intersect_extension(&curr, *scan_ptr); ha_rows records= records_in_index_intersect_extension(&curr, *scan_ptr);
(*scan_ptr)->filtered_out= records >= scan_records ? (*scan_ptr)->filtered_out= records >= scan_records ?
0 : scan_records-records; 0 : scan_records-records;
if (thd->trace_started()) if (unlikely(thd->trace_started()))
{ {
Json_writer_object selected_idx(thd); Json_writer_object selected_idx(thd);
selected_idx.add("index", key_info->name); selected_idx.add("index", key_info->name);
print_keyparts(thd, key_info, (*scan_ptr)->used_key_parts); print_keyparts(thd, key_info, (*scan_ptr)->used_key_parts);
selected_idx.add("records", (*scan_ptr)->records) selected_idx.
.add("filtered_records", (*scan_ptr)->filtered_out); add("records", (*scan_ptr)->records).
add("filtered_records", (*scan_ptr)->filtered_out);
} }
} }
} }
@ -6005,13 +6042,14 @@ bool prepare_search_best_index_intersect(PARAM *param,
{ {
KEY *key_info= (*scan_ptr)->key_info; KEY *key_info= (*scan_ptr)->key_info;
(*scan_ptr)->filtered_out= 0; (*scan_ptr)->filtered_out= 0;
if (thd->trace_started()) if (unlikely(thd->trace_started()))
{ {
Json_writer_object selected_idx(thd); Json_writer_object selected_idx(thd);
selected_idx.add("index", key_info->name); selected_idx.add("index", key_info->name);
print_keyparts(thd, key_info, (*scan_ptr)->used_key_parts); print_keyparts(thd, key_info, (*scan_ptr)->used_key_parts);
selected_idx.add("records", (*scan_ptr)->records) selected_idx.
.add("filtered_records", (*scan_ptr)->filtered_out); add("records", (*scan_ptr)->records).
add("filtered_records", (*scan_ptr)->filtered_out);
} }
} }
} }
@ -6544,9 +6582,11 @@ TRP_INDEX_INTERSECT *get_best_index_intersect(PARAM *param, SEL_TREE *tree,
intersect_trp->range_scans= range_scans; intersect_trp->range_scans= range_scans;
intersect_trp->range_scans_end= cur_range; intersect_trp->range_scans_end= cur_range;
intersect_trp->filtered_scans= common.filtered_scans; intersect_trp->filtered_scans= common.filtered_scans;
trace_idx_interect.add("rows", intersect_trp->records) if (unlikely(trace_idx_interect.trace_started()))
.add("cost", intersect_trp->read_cost) trace_idx_interect.
.add("chosen",true); add("rows", intersect_trp->records).
add("cost", intersect_trp->read_cost).
add("chosen",true);
} }
DBUG_RETURN(intersect_trp); DBUG_RETURN(intersect_trp);
} }
@ -6562,11 +6602,12 @@ void TRP_ROR_INTERSECT::trace_basic_info(PARAM *param,
THD *thd= param->thd; THD *thd= param->thd;
DBUG_ASSERT(trace_object->trace_started()); DBUG_ASSERT(trace_object->trace_started());
trace_object->add("type", "index_roworder_intersect"); trace_object->
trace_object->add("rows", records); add("type", "index_roworder_intersect").
trace_object->add("cost", read_cost); add("rows", records).
trace_object->add("covering", is_covering); add("cost", read_cost).
trace_object->add("clustered_pk_scan", cpk_scan != NULL); add("covering", is_covering).
add("clustered_pk_scan", cpk_scan != NULL);
Json_writer_array smth_trace(thd, "intersect_of"); Json_writer_array smth_trace(thd, "intersect_of");
for (ROR_SCAN_INFO **cur_scan= first_scan; cur_scan != last_scan; for (ROR_SCAN_INFO **cur_scan= first_scan; cur_scan != last_scan;
@ -6576,9 +6617,10 @@ void TRP_ROR_INTERSECT::trace_basic_info(PARAM *param,
const KEY_PART_INFO *key_part= cur_key.key_part; const KEY_PART_INFO *key_part= cur_key.key_part;
Json_writer_object trace_isect_idx(thd); Json_writer_object trace_isect_idx(thd);
trace_isect_idx.add("type", "range_scan"); trace_isect_idx.
trace_isect_idx.add("index", cur_key.name); add("type", "range_scan").
trace_isect_idx.add("rows", (*cur_scan)->records); add("index", cur_key.name).
add("rows", (*cur_scan)->records);
Json_writer_array trace_range(thd, "ranges"); Json_writer_array trace_range(thd, "ranges");
@ -7217,16 +7259,18 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
/* S= S + first(R); R= R - first(R); */ /* S= S + first(R); R= R - first(R); */
if (!ror_intersect_add(intersect, *cur_ror_scan, &trace_idx, FALSE)) if (!ror_intersect_add(intersect, *cur_ror_scan, &trace_idx, FALSE))
{ {
trace_idx.add("usable", false) trace_idx.
.add("cause", "does not reduce cost of intersect"); add("usable", false).
add("cause", "does not reduce cost of intersect");
cur_ror_scan++; cur_ror_scan++;
continue; continue;
} }
trace_idx.add("cumulative_total_cost", intersect->total_cost) trace_idx.
.add("usable", true) add("cumulative_total_cost", intersect->total_cost).
.add("matching_rows_now", intersect->out_rows) add("usable", true).
.add("intersect_covering_with_this_index", intersect->is_covering); add("matching_rows_now", intersect->out_rows).
add("intersect_covering_with_this_index", intersect->is_covering);
*(intersect_scans_end++)= *(cur_ror_scan++); *(intersect_scans_end++)= *(cur_ror_scan++);
@ -7240,8 +7284,9 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
} }
else else
{ {
trace_idx.add("chosen", false) trace_idx.
.add("cause", "does not reduce cost"); add("chosen", false).
add("cause", "does not reduce cost");
} }
} }
trace_isect_idx.end(); trace_isect_idx.end();
@ -7249,8 +7294,9 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
if (intersect_scans_best == intersect_scans) if (intersect_scans_best == intersect_scans)
{ {
DBUG_PRINT("info", ("None of scans increase selectivity")); DBUG_PRINT("info", ("None of scans increase selectivity"));
trace_ror.add("chosen", false) trace_ror.
.add("cause","does not increase selectivity"); add("chosen", false).
add("cause","does not increase selectivity");
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }
@ -7274,22 +7320,27 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
if (ror_intersect_add(intersect, cpk_scan, &trace_cpk, TRUE) && if (ror_intersect_add(intersect, cpk_scan, &trace_cpk, TRUE) &&
(intersect->total_cost < min_cost)) (intersect->total_cost < min_cost))
{ {
trace_cpk.add("clustered_pk_scan_added_to_intersect", true) if (trace_cpk.trace_started())
.add("cumulated_cost", intersect->total_cost); trace_cpk.
add("clustered_pk_scan_added_to_intersect", true).
add("cumulated_cost", intersect->total_cost);
intersect_best= intersect; //just set pointer here intersect_best= intersect; //just set pointer here
} }
else else
{ {
trace_cpk.add("clustered_pk_added_to_intersect", false) if (trace_cpk.trace_started())
.add("cause", "cost"); trace_cpk.
add("clustered_pk_added_to_intersect", false).
add("cause", "cost");
cpk_scan= 0; // Don't use cpk_scan cpk_scan= 0; // Don't use cpk_scan
} }
} }
else else
{ {
trace_cpk.add("clustered_pk_added_to_intersect", false) trace_cpk.
.add("cause", cpk_scan ? "roworder is covering" add("clustered_pk_added_to_intersect", false).
: "no clustered pk index"); add("cause", cpk_scan ? "roworder is covering"
: "no clustered pk index");
cpk_scan= 0; // Don't use cpk_scan cpk_scan= 0; // Don't use cpk_scan
} }
trace_cpk.end(); trace_cpk.end();
@ -7319,17 +7370,20 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
DBUG_PRINT("info", ("Returning non-covering ROR-intersect plan:" DBUG_PRINT("info", ("Returning non-covering ROR-intersect plan:"
"cost %g, records %lu", "cost %g, records %lu",
trp->read_cost, (ulong) trp->records)); trp->read_cost, (ulong) trp->records));
trace_ror.add("rows", trp->records) if (unlikely(trace_ror.trace_started()))
.add("cost", trp->read_cost) trace_ror.
.add("covering", trp->is_covering) add("rows", trp->records).
.add("chosen", true); add("cost", trp->read_cost).
add("covering", trp->is_covering).
add("chosen", true);
} }
else else
{ {
trace_ror.add("chosen", false) trace_ror.
.add("cause", (read_time > min_cost) add("chosen", false).
? "too few indexes to merge" add("cause", (read_time >= min_cost)
: "cost"); ? "too few indexes to merge"
: "cost");
} }
DBUG_PRINT("enter", ("opt_range_condition_rows: %llu", DBUG_PRINT("enter", ("opt_range_condition_rows: %llu",
(ulonglong) param->table->opt_range_condition_rows)); (ulonglong) param->table->opt_range_condition_rows));
@ -7597,11 +7651,13 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
trace_ranges(&trace_range, param, idx, key, key_part); trace_ranges(&trace_range, param, idx, key, key_part);
trace_range.end(); trace_range.end();
trace_idx.add("rowid_ordered", is_ror_scan) if (unlikely(trace_idx.trace_started()))
.add("using_mrr", !(mrr_flags & HA_MRR_USE_DEFAULT_IMPL)) trace_idx.
.add("index_only", read_index_only) add("rowid_ordered", is_ror_scan).
.add("rows", found_records) add("using_mrr", !(mrr_flags & HA_MRR_USE_DEFAULT_IMPL)).
.add("cost", cost.total_cost()); add("index_only", read_index_only).
add("rows", found_records).
add("cost", cost.total_cost());
} }
if ((found_records != HA_POS_ERROR) && is_ror_scan) if ((found_records != HA_POS_ERROR) && is_ror_scan)
{ {
@ -7619,7 +7675,7 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
best_buf_size= buf_size; best_buf_size= buf_size;
trace_idx.add("chosen", true); trace_idx.add("chosen", true);
} }
else else if (unlikely(trace_idx.trace_started()))
{ {
trace_idx.add("chosen", false); trace_idx.add("chosen", false);
if (found_records == HA_POS_ERROR) if (found_records == HA_POS_ERROR)
@ -11038,7 +11094,7 @@ SEL_ARG *enforce_sel_arg_weight_limit(RANGE_OPT_PARAM *param, uint keyno,
uint weight2= sel_arg? sel_arg->weight : 0; uint weight2= sel_arg? sel_arg->weight : 0;
if (weight2 != weight1) if (unlikely(weight2 != weight1 && param->thd->trace_started()))
{ {
Json_writer_object wrapper(param->thd); Json_writer_object wrapper(param->thd);
Json_writer_object obj(param->thd, "enforce_sel_arg_weight_limit"); Json_writer_object obj(param->thd, "enforce_sel_arg_weight_limit");
@ -11047,8 +11103,9 @@ SEL_ARG *enforce_sel_arg_weight_limit(RANGE_OPT_PARAM *param, uint keyno,
else else
obj.add("pseudo_index", field->field_name); obj.add("pseudo_index", field->field_name);
obj.add("old_weight", (longlong)weight1); obj.
obj.add("new_weight", (longlong)weight2); add("old_weight", (longlong)weight1).
add("new_weight", (longlong)weight2);
} }
return sel_arg; return sel_arg;
} }
@ -11072,12 +11129,16 @@ bool sel_arg_and_weight_heuristic(RANGE_OPT_PARAM *param, SEL_ARG *key1,
ulong max_weight= param->thd->variables.optimizer_max_sel_arg_weight; ulong max_weight= param->thd->variables.optimizer_max_sel_arg_weight;
if (max_weight && key1->weight + key1->elements*key2->weight > max_weight) if (max_weight && key1->weight + key1->elements*key2->weight > max_weight)
{ {
Json_writer_object wrapper(param->thd); if (unlikely(param->thd->trace_started()))
Json_writer_object obj(param->thd, "sel_arg_weight_heuristic"); {
obj.add("key1_field", key1->field->field_name); Json_writer_object wrapper(param->thd);
obj.add("key2_field", key2->field->field_name); Json_writer_object obj(param->thd, "sel_arg_weight_heuristic");
obj.add("key1_weight", (longlong)key1->weight); obj.
obj.add("key2_weight", (longlong)key2->weight); add("key1_field", key1->field->field_name).
add("key2_field", key2->field->field_name).
add("key1_weight", (longlong)key1->weight).
add("key2_weight", (longlong)key2->weight);
}
return true; // Discard key2 return true; // Discard key2
} }
return false; return false;
@ -13805,7 +13866,8 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time)
(!join->select_distinct) && (!join->select_distinct) &&
!is_agg_distinct) !is_agg_distinct)
{ {
trace_group.add("chosen", false).add("cause","no group by or distinct"); if (unlikely(trace_group.trace_started()))
trace_group.add("chosen", false).add("cause","no group by or distinct");
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }
/* Analyze the query in more detail. */ /* Analyze the query in more detail. */
@ -13830,8 +13892,10 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time)
continue; continue;
else else
{ {
trace_group.add("chosen", false) if (unlikely(trace_group.trace_started()))
.add("cause", "not applicable aggregate function"); trace_group.
add("chosen", false).
add("cause", "not applicable aggregate function");
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }
@ -13843,15 +13907,19 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time)
min_max_arg_item= (Item_field*) expr; min_max_arg_item= (Item_field*) expr;
else if (! min_max_arg_item->eq(expr, 1)) else if (! min_max_arg_item->eq(expr, 1))
{ {
trace_group.add("chosen", false) if (unlikely(trace_group.trace_started()))
.add("cause", "arguments different in min max function"); trace_group.
add("chosen", false).
add("cause", "arguments different in min max function");
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }
} }
else else
{ {
trace_group.add("chosen", false) if (unlikely(trace_group.trace_started()))
.add("cause", "no field item in min max function"); trace_group.
add("chosen", false).
add("cause", "no field item in min max function");
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }
} }
@ -13860,8 +13928,10 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time)
/* Check (SA7). */ /* Check (SA7). */
if (is_agg_distinct && (have_max || have_min)) if (is_agg_distinct && (have_max || have_min))
{ {
trace_group.add("chosen", false) if (unlikely(trace_group.trace_started()))
.add("cause", "have both agg distinct and min max"); trace_group.
add("chosen", false).
add("cause", "have both agg distinct and min max");
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }
@ -13873,8 +13943,10 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time)
{ {
if (item->real_item()->type() != Item::FIELD_ITEM) if (item->real_item()->type() != Item::FIELD_ITEM)
{ {
trace_group.add("chosen", false) if (unlikely(trace_group.trace_started()))
.add("cause", "distinct field is expression"); trace_group.
add("chosen", false).
add("cause", "distinct field is expression");
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }
} }
@ -13886,8 +13958,10 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time)
{ {
if ((*tmp_group->item)->real_item()->type() != Item::FIELD_ITEM) if ((*tmp_group->item)->real_item()->type() != Item::FIELD_ITEM)
{ {
trace_group.add("chosen", false) if (unlikely(trace_group.trace_started()))
.add("cause", "group field is expression"); trace_group.
add("chosen", false).
add("cause", "group field is expression");
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }
elements_in_group++; elements_in_group++;
@ -14313,8 +14387,10 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time)
Field::itMBR : Field::itRAW, Field::itMBR : Field::itRAW,
&has_min_max_fld, &has_other_fld)) &has_min_max_fld, &has_other_fld))
{ {
trace_group.add("usable", false) if (unlikely(trace_group.trace_started()))
.add("cause", "unsupported predicate on agg attribute"); trace_group.
add("usable", false).
add("cause", "unsupported predicate on agg attribute");
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }
@ -14323,8 +14399,10 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time)
*/ */
if (is_agg_distinct && table->file->is_clustering_key(index)) if (is_agg_distinct && table->file->is_clustering_key(index))
{ {
trace_group.add("usable", false) if (unlikely(trace_group.trace_started()))
.add("cause", "index is clustered"); trace_group.
add("usable", false).
add("cause", "index is clustered");
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }

View File

@ -1014,11 +1014,12 @@ SplM_plan_info * JOIN_TAB::choose_best_splitting(double record_count,
{ {
Json_writer_object wrapper(thd); Json_writer_object wrapper(thd);
Json_writer_object find_trace(thd, "best_splitting"); Json_writer_object find_trace(thd, "best_splitting");
find_trace.add("table", best_table->alias.c_ptr()); find_trace.
find_trace.add("key", best_table->key_info[best_key].name); add("table", best_table->alias.c_ptr()).
find_trace.add("record_count", record_count); add("key", best_table->key_info[best_key].name).
find_trace.add("cost", spl_plan->cost); add("record_count", record_count).
find_trace.add("unsplit_cost", spl_opt_info->unsplit_cost); add("cost", spl_plan->cost).
add("unsplit_cost", spl_opt_info->unsplit_cost);
} }
memcpy((char *) spl_plan->best_positions, memcpy((char *) spl_plan->best_positions,
(char *) join->best_positions, (char *) join->best_positions,
@ -1047,10 +1048,14 @@ SplM_plan_info * JOIN_TAB::choose_best_splitting(double record_count,
startup_cost= record_count * spl_plan->cost; startup_cost= record_count * spl_plan->cost;
records= (ha_rows) (records * spl_plan->split_sel); records= (ha_rows) (records * spl_plan->split_sel);
Json_writer_object trace(thd, "lateral_derived"); if (unlikely(thd->trace_started()))
trace.add("startup_cost", startup_cost); {
trace.add("splitting_cost", spl_plan->cost); Json_writer_object trace(thd, "lateral_derived");
trace.add("records", records); trace.
add("startup_cost", startup_cost).
add("splitting_cost", spl_plan->cost).
add("records", records);
}
} }
else else
startup_cost= spl_opt_info->unsplit_cost; startup_cost= spl_opt_info->unsplit_cost;

View File

@ -910,8 +910,10 @@ bool subquery_types_allow_materialization(THD* thd, Item_in_subselect *in_subs)
outer, outer,
converted_from_in_predicate)) converted_from_in_predicate))
{ {
trace_transform.add("possible", false); if (unlikely(trace_transform.trace_started()))
trace_transform.add("cause", "types mismatch"); trace_transform.
add("possible", false).
add("cause", "types mismatch");
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} }
} }
@ -933,8 +935,10 @@ bool subquery_types_allow_materialization(THD* thd, Item_in_subselect *in_subs)
{ {
in_subs->types_allow_materialization= TRUE; in_subs->types_allow_materialization= TRUE;
in_subs->sjm_scan_allowed= all_are_fields; in_subs->sjm_scan_allowed= all_are_fields;
trace_transform.add("sjm_scan_allowed", all_are_fields) if (unlikely(trace_transform.trace_started()))
.add("possible", true); trace_transform.
add("sjm_scan_allowed", all_are_fields).
add("possible", true);
DBUG_PRINT("info",("subquery_types_allow_materialization: ok, allowed")); DBUG_PRINT("info",("subquery_types_allow_materialization: ok, allowed"));
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
@ -1294,8 +1298,10 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
OPT_TRACE_TRANSFORM(thd, trace_wrapper, trace_transform, OPT_TRACE_TRANSFORM(thd, trace_wrapper, trace_transform,
in_subq->get_select_lex()->select_number, in_subq->get_select_lex()->select_number,
"IN (SELECT)", "semijoin"); "IN (SELECT)", "semijoin");
trace_transform.add("converted_to_semi_join", false) if (unlikely(trace_transform.trace_started()))
.add("cause", "subquery attached to the ON clause"); trace_transform.
add("converted_to_semi_join", false).
add("cause", "subquery attached to the ON clause");
break; break;
} }
@ -1307,9 +1313,10 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
if (join->table_count + if (join->table_count +
in_subq->unit->first_select()->join->table_count >= MAX_TABLES) in_subq->unit->first_select()->join->table_count >= MAX_TABLES)
{ {
trace_transform.add("converted_to_semi_join", false); if (unlikely(trace_transform.trace_started()))
trace_transform.add("cause", trace_transform.
"table in parent join now exceeds MAX_TABLES"); add("converted_to_semi_join", false).
add("cause", "table in parent join now exceeds MAX_TABLES");
break; break;
} }
if (convert_subq_to_sj(join, in_subq)) if (convert_subq_to_sj(join, in_subq))
@ -3147,8 +3154,9 @@ bool Sj_materialization_picker::check_qep(JOIN *join,
*strategy= SJ_OPT_MATERIALIZE; *strategy= SJ_OPT_MATERIALIZE;
if (unlikely(trace.trace_started())) if (unlikely(trace.trace_started()))
{ {
trace.add("records", *record_count); trace.
trace.add("read_time", *read_time); add("records", *record_count).
add("cost", *read_time);
} }
return TRUE; return TRUE;
} }
@ -3329,8 +3337,9 @@ bool LooseScan_picker::check_qep(JOIN *join,
*handled_fanout= first->table->emb_sj_nest->sj_inner_tables; *handled_fanout= first->table->emb_sj_nest->sj_inner_tables;
if (unlikely(trace.trace_started())) if (unlikely(trace.trace_started()))
{ {
trace.add("records", *record_count); trace.
trace.add("read_time", *read_time); add("records", *record_count).
add("read_time", *read_time);
} }
return TRUE; return TRUE;
} }

View File

@ -149,7 +149,7 @@ void opt_trace_disable_if_no_security_context_access(THD *thd)
return; return;
} }
Opt_trace_context *const trace= &thd->opt_trace; Opt_trace_context *const trace= &thd->opt_trace;
if (!thd->trace_started()) if (unlikely(!thd->trace_started()))
{ {
/* /*
@@optimizer_trace has "enabled=on" but trace is not started. @@optimizer_trace has "enabled=on" but trace is not started.
@ -201,7 +201,7 @@ void opt_trace_disable_if_no_stored_proc_func_access(THD *thd, sp_head *sp)
if (likely(!(thd->variables.optimizer_trace & if (likely(!(thd->variables.optimizer_trace &
Opt_trace_context::FLAG_ENABLED)) || Opt_trace_context::FLAG_ENABLED)) ||
thd->system_thread || thd->system_thread ||
!thd->trace_started()) likely(!thd->trace_started()))
return; return;
Opt_trace_context *const trace= &thd->opt_trace; Opt_trace_context *const trace= &thd->opt_trace;
@ -235,7 +235,7 @@ void opt_trace_disable_if_no_tables_access(THD *thd, TABLE_LIST *tbl)
if (likely(!(thd->variables.optimizer_trace & if (likely(!(thd->variables.optimizer_trace &
Opt_trace_context::FLAG_ENABLED)) || Opt_trace_context::FLAG_ENABLED)) ||
thd->system_thread || thd->system_thread ||
!thd->trace_started()) likely(!thd->trace_started()))
return; return;
Opt_trace_context *const trace= &thd->opt_trace; Opt_trace_context *const trace= &thd->opt_trace;
@ -296,7 +296,7 @@ void opt_trace_disable_if_no_view_access(THD *thd, TABLE_LIST *view,
if (likely(!(thd->variables.optimizer_trace & if (likely(!(thd->variables.optimizer_trace &
Opt_trace_context::FLAG_ENABLED)) || Opt_trace_context::FLAG_ENABLED)) ||
thd->system_thread || thd->system_thread ||
!thd->trace_started()) likely(!thd->trace_started()))
return; return;
Opt_trace_context *const trace= &thd->opt_trace; Opt_trace_context *const trace= &thd->opt_trace;
@ -605,6 +605,7 @@ void Json_writer::add_table_name(const TABLE *table)
void trace_condition(THD * thd, const char *name, const char *transform_type, void trace_condition(THD * thd, const char *name, const char *transform_type,
Item *item, const char *table_name) Item *item, const char *table_name)
{ {
DBUG_ASSERT(thd->trace_started());
Json_writer_object trace_wrapper(thd); Json_writer_object trace_wrapper(thd);
Json_writer_object trace_cond(thd, transform_type); Json_writer_object trace_cond(thd, transform_type);
trace_cond.add("condition", name); trace_cond.add("condition", name);
@ -620,8 +621,9 @@ void add_table_scan_values_to_trace(THD *thd, JOIN_TAB *tab)
Json_writer_object table_records(thd); Json_writer_object table_records(thd);
table_records.add_table_name(tab); table_records.add_table_name(tab);
Json_writer_object table_rec(thd, "table_scan"); Json_writer_object table_rec(thd, "table_scan");
table_rec.add("rows", tab->found_records) table_rec.
.add("cost", tab->read_time); add("rows", tab->found_records).
add("cost", tab->read_time);
} }
@ -690,10 +692,11 @@ void print_best_access_for_table(THD *thd, POSITION *pos,
DBUG_ASSERT(thd->trace_started()); DBUG_ASSERT(thd->trace_started());
Json_writer_object obj(thd, "chosen_access_method"); Json_writer_object obj(thd, "chosen_access_method");
obj.add("type", type == JT_ALL ? "scan" : join_type_str[type]); obj.
obj.add("records", pos->records_read); add("type", type == JT_ALL ? "scan" : join_type_str[type]).
obj.add("cost", pos->read_time); add("records", pos->records_read).
obj.add("uses_join_buffering", pos->use_join_buffer); add("cost", pos->read_time).
add("uses_join_buffering", pos->use_join_buffer);
if (pos->range_rowid_filter_info) if (pos->range_rowid_filter_info)
{ {
uint key_no= pos->range_rowid_filter_info->get_key_no(); uint key_no= pos->range_rowid_filter_info->get_key_no();

View File

@ -423,6 +423,7 @@ void TABLE::init_cost_info_for_usable_range_rowid_filters(THD *thd)
void TABLE::trace_range_rowid_filters(THD *thd) const void TABLE::trace_range_rowid_filters(THD *thd) const
{ {
DBUG_ASSERT(thd->trace_started());
if (!range_rowid_filter_cost_info_elems) if (!range_rowid_filter_cost_info_elems)
return; return;
@ -440,10 +441,12 @@ void TABLE::trace_range_rowid_filters(THD *thd) const
void Range_rowid_filter_cost_info::trace_info(THD *thd) void Range_rowid_filter_cost_info::trace_info(THD *thd)
{ {
DBUG_ASSERT(thd->trace_started());
Json_writer_object js_obj(thd); Json_writer_object js_obj(thd);
js_obj.add("key", table->key_info[key_no].name); js_obj.
js_obj.add("build_cost", cost_of_building_range_filter); add("key", table->key_info[key_no].name).
js_obj.add("rows", est_elements); add("build_cost", cost_of_building_range_filter).
add("rows", est_elements);
} }
/** /**

View File

@ -538,9 +538,10 @@ static void trace_table_dependencies(THD *thd,
{ {
TABLE_LIST *table_ref= join_tabs[i].tab_list; TABLE_LIST *table_ref= join_tabs[i].tab_list;
Json_writer_object trace_one_table(thd); Json_writer_object trace_one_table(thd);
trace_one_table.add_table_name(&join_tabs[i]); trace_one_table.
trace_one_table.add("row_may_be_null", add_table_name(&join_tabs[i]).
(bool)table_ref->table->maybe_null); add("row_may_be_null",
(bool)table_ref->table->maybe_null);
const table_map map= table_ref->get_map(); const table_map map= table_ref->get_map();
DBUG_ASSERT(map < (1ULL << table_count)); DBUG_ASSERT(map < (1ULL << table_count));
for (uint j= 0; j < table_count; j++) for (uint j= 0; j < table_count; j++)
@ -1742,7 +1743,7 @@ JOIN::prepare(TABLE_LIST *tables_init, COND *conds_init, uint og_num,
} }
} }
if (thd->trace_started()) if (unlikely(thd->trace_started()))
{ {
Json_writer_object trace_wrapper(thd); Json_writer_object trace_wrapper(thd);
opt_trace_print_expanded_query(thd, select_lex, &trace_wrapper); opt_trace_print_expanded_query(thd, select_lex, &trace_wrapper);
@ -5487,7 +5488,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
} }
} }
if (thd->trace_started()) if (unlikely(thd->trace_started()))
trace_table_dependencies(thd, stat, join->table_count); trace_table_dependencies(thd, stat, join->table_count);
if (join->conds || outer_join) if (join->conds || outer_join)
@ -5508,7 +5509,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
skip_unprefixed_keyparts)) skip_unprefixed_keyparts))
goto error; goto error;
DBUG_EXECUTE("opt", print_keyuse_array(keyuse_array);); DBUG_EXECUTE("opt", print_keyuse_array(keyuse_array););
if (thd->trace_started()) if (unlikely(thd->trace_started()))
print_keyuse_array_for_trace(thd, keyuse_array); print_keyuse_array_for_trace(thd, keyuse_array);
} }
@ -5957,13 +5958,13 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
delete select; delete select;
else else
{ {
if (thd->trace_started()) if (unlikely(thd->trace_started()))
add_table_scan_values_to_trace(thd, s); add_table_scan_values_to_trace(thd, s);
} }
} }
else else
{ {
if (thd->trace_started()) if (unlikely(thd->trace_started()))
add_table_scan_values_to_trace(thd, s); add_table_scan_values_to_trace(thd, s);
} }
} }
@ -8083,8 +8084,10 @@ best_access_path(JOIN *join,
*/ */
records= 1.0; records= 1.0;
type= JT_FT; type= JT_FT;
trace_access_idx.add("access_type", join_type_str[type]) if (unlikely(trace_access_idx.trace_started()))
.add("full-text index", keyinfo->name); trace_access_idx.
add("access_type", join_type_str[type]).
add("full-text index", keyinfo->name);
} }
else else
{ {
@ -8109,8 +8112,10 @@ best_access_path(JOIN *join,
DBUG_ASSERT(join->eq_ref_tables & table->map); DBUG_ASSERT(join->eq_ref_tables & table->map);
/* TODO: Adjust cost for covering and clustering key */ /* TODO: Adjust cost for covering and clustering key */
type= JT_EQ_REF; type= JT_EQ_REF;
trace_access_idx.add("access_type", join_type_str[type]) if (unlikely(trace_access_idx.trace_started()))
.add("index", keyinfo->name); trace_access_idx.
add("access_type", join_type_str[type]).
add("index", keyinfo->name);
if (!found_ref && table->opt_range_keys.is_set(key)) if (!found_ref && table->opt_range_keys.is_set(key))
tmp= adjust_quick_cost(table->opt_range[key].cost, 1); tmp= adjust_quick_cost(table->opt_range[key].cost, 1);
else else
@ -8126,8 +8131,10 @@ best_access_path(JOIN *join,
else else
{ {
type= JT_REF; type= JT_REF;
trace_access_idx.add("access_type", join_type_str[type]) if (unlikely(trace_access_idx.trace_started()))
.add("index", keyinfo->name); trace_access_idx.
add("access_type", join_type_str[type]).
add("index", keyinfo->name);
if (!found_ref) if (!found_ref)
{ /* We found a const key */ { /* We found a const key */
/* /*
@ -8157,8 +8164,10 @@ best_access_path(JOIN *join,
} }
/* quick_range couldn't use key! */ /* quick_range couldn't use key! */
records= (double) s->records/rec; records= (double) s->records/rec;
trace_access_idx.add("used_range_estimates", false) if (unlikely(trace_access_idx.trace_started()))
.add("reason", "not available"); trace_access_idx.
add("used_range_estimates", false).
add("reason", "not available");
} }
else else
{ {
@ -8193,16 +8202,19 @@ best_access_path(JOIN *join,
records= (double) table->opt_range[key].rows; records= (double) table->opt_range[key].rows;
trace_access_idx.add("used_range_estimates", "clipped down"); trace_access_idx.add("used_range_estimates", "clipped down");
} }
else else if (unlikely(trace_access_idx.trace_started()))
{ {
trace_access_idx.add("used_range_estimates", false);
if (table->opt_range_keys.is_set(key)) if (table->opt_range_keys.is_set(key))
{ {
trace_access_idx.add("reason", "not better than ref estimates"); trace_access_idx.
add("used_range_estimates",false).
add("reason", "not better than ref estimates");
} }
else else
{ {
trace_access_idx.add("reason", "not available"); trace_access_idx.
add("used_range_estimates", false).
add("reason", "not available");
} }
} }
} }
@ -8214,8 +8226,10 @@ best_access_path(JOIN *join,
else else
{ {
type = ref_or_null_part ? JT_REF_OR_NULL : JT_REF; type = ref_or_null_part ? JT_REF_OR_NULL : JT_REF;
trace_access_idx.add("access_type", join_type_str[type]) if (unlikely(trace_access_idx.trace_started()))
.add("index", keyinfo->name); trace_access_idx.
add("access_type", join_type_str[type]).
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
than a not unique key than a not unique key
@ -8506,16 +8520,21 @@ best_access_path(JOIN *join,
} }
} }
tmp= COST_ADD(tmp, records_after_filter/TIME_FOR_COMPARE); tmp= COST_ADD(tmp, records_after_filter/TIME_FOR_COMPARE);
trace_access_idx. if (unlikely(trace_access_idx.trace_started()))
add("rows", records). trace_access_idx.
add("cond_check_cost",tmp). add("rows", records).
add("startup_cost", startup_cost); add("cond_check_cost",tmp).
add("startup_cost", startup_cost);
tmp= COST_MULT(tmp, record_count); tmp= COST_MULT(tmp, record_count);
tmp= COST_ADD(tmp, startup_cost); tmp= COST_ADD(tmp, startup_cost);
if (unlikely(trace_access_idx.trace_started()))
trace_access_idx.add("rows_after_filter", records_after_filter).add("cost", tmp);
if (tmp + 0.0001 < best_cost) if (tmp + 0.0001 < best_cost)
{ {
trace_access_idx.add("cost", tmp).add("chosen", true); trace_access_idx.add("chosen", true);
best_cost= tmp; best_cost= tmp;
best_records= records; best_records= records;
best_key= start_key; best_key= start_key;
@ -8524,10 +8543,11 @@ best_access_path(JOIN *join,
best_filter= filter; best_filter= filter;
best_type= type; best_type= type;
} }
else if (thd->trace_started()) else if (unlikely(thd->trace_started()))
{ {
trace_access_idx.add("cost",tmp).add("chosen", false) trace_access_idx.
.add("cause", cause ? cause : "cost"); add("chosen", false).
add("cause", cause ? cause : "cost");
} }
} /* for each key */ } /* for each key */
records= best_records; records= best_records;
@ -8627,11 +8647,14 @@ best_access_path(JOIN *join,
best_filter= 0; best_filter= 0;
best_type= JT_HASH; best_type= JT_HASH;
Json_writer_object trace_access_hash(thd); Json_writer_object trace_access_hash(thd);
trace_access_hash.add("type", "hash"); if (unlikely(trace_access_hash.trace_started()))
trace_access_hash.add("index", "hj-key"); trace_access_hash.
trace_access_hash.add("rows", rnd_records); add("type", "hash").
trace_access_hash.add("cost", best_cost); add("index", "hj-key").
trace_access_hash.add("chosen", true); add("rows", rnd_records).
add("refills", refills).
add("cost", best_cost).
add("chosen", true);
} }
/* /*
@ -8819,8 +8842,10 @@ best_access_path(JOIN *join,
best_filter_cmp_gain= (best_filter ? best_filter_cmp_gain= (best_filter ?
best_filter->get_cmp_gain(record_count * records) : best_filter->get_cmp_gain(record_count * records) :
0); 0);
trace_access_scan.add("resulting_rows", rnd_records); if (unlikely(trace_access_scan.trace_started()))
trace_access_scan.add("cost", tmp); trace_access_scan.
add("resulting_rows", rnd_records).
add("cost", tmp);
/* TODO: Document the following if */ /* TODO: Document the following if */
if (best_cost == DBL_MAX || if (best_cost == DBL_MAX ||
@ -8851,9 +8876,11 @@ best_access_path(JOIN *join,
} }
else else
{ {
trace_access_scan.add("type", "scan"); if (unlikely(trace_access_scan.trace_started()))
trace_access_scan.add("chosen", false); trace_access_scan.
trace_access_scan.add("cause", "cost"); add("type", "scan").
add("chosen", false).
add("cause", "cost");
} }
/* Update the cost information for the current partial plan */ /* Update the cost information for the current partial plan */
@ -10605,10 +10632,11 @@ best_extension_by_limited_search(JOIN *join,
current_record_count / current_record_count /
TIME_FOR_COMPARE)); TIME_FOR_COMPARE));
if (unlikely(thd->trace_started())) if (unlikely(trace_one_table.trace_started()))
{ {
trace_one_table.add("rows_for_plan", current_record_count); trace_one_table.
trace_one_table.add("cost_for_plan", current_read_time); add("rows_for_plan", current_record_count).
add("cost_for_plan", current_read_time);
} }
optimize_semi_joins(join, remaining_tables, idx, &current_record_count, optimize_semi_joins(join, remaining_tables, idx, &current_record_count,
&current_read_time, loose_scan_pos); &current_read_time, loose_scan_pos);
@ -12514,8 +12542,10 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
trace_const_cond.add("condition_on_constant_tables", const_cond); trace_const_cond.add("condition_on_constant_tables", const_cond);
if (const_cond->is_expensive()) if (const_cond->is_expensive())
{ {
trace_const_cond.add("evaluated", "false") if (unlikely(trace_const_cond.trace_started()))
.add("cause", "expensive cond"); trace_const_cond.
add("evalualted", "false").
add("cause", "expensive cond");
} }
else else
{ {
@ -12527,8 +12557,10 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
if (!const_cond_result) if (!const_cond_result)
{ {
DBUG_PRINT("info",("Found impossible WHERE condition")); DBUG_PRINT("info",("Found impossible WHERE condition"));
trace_const_cond.add("evaluated", "true") if (unlikely(trace_const_cond.trace_started()))
.add("found", "impossible where"); trace_const_cond.
add("evalualted", "true").
add("found", "impossible where");
join->exec_const_cond= NULL; join->exec_const_cond= NULL;
DBUG_RETURN(1); DBUG_RETURN(1);
} }
@ -12631,9 +12663,13 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
tab->table->intersect_keys.is_set(tab->ref.key)))) tab->table->intersect_keys.is_set(tab->ref.key))))
{ {
/* Range uses longer key; Use this instead of ref on key */ /* Range uses longer key; Use this instead of ref on key */
Json_writer_object ref_to_range(thd); if (unlikely(thd->trace_started()))
ref_to_range.add("ref_to_range", true); {
ref_to_range.add("cause", "range uses longer key"); Json_writer_object ref_to_range(thd);
ref_to_range.
add("ref_to_range", true).
add("cause", "range uses longer key");
}
tab->type=JT_ALL; tab->type=JT_ALL;
use_quick_range=1; use_quick_range=1;
tab->use_quick=1; tab->use_quick=1;
@ -13144,8 +13180,9 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
continue; continue;
Item *const cond = tab->select_cond; Item *const cond = tab->select_cond;
Json_writer_object trace_one_table(thd); Json_writer_object trace_one_table(thd);
trace_one_table.add_table_name(tab); trace_one_table.
trace_one_table.add("attached", cond); add_table_name(tab).
add("attached", cond);
} }
} }
} }
@ -18395,8 +18432,11 @@ optimize_cond(JOIN *join, COND *conds,
Json_writer_object trace_wrapper(thd); Json_writer_object trace_wrapper(thd);
Json_writer_object trace_cond(thd, "condition_processing"); Json_writer_object trace_cond(thd, "condition_processing");
trace_cond.add("condition", join->conds == conds ? "WHERE" : "HAVING")
.add("original_condition", conds); if (unlikely(trace_cond.trace_started()))
trace_cond.
add("condition", join->conds == conds ? "WHERE" : "HAVING").
add("original_condition", conds);
Json_writer_array trace_steps(thd, "steps"); Json_writer_array trace_steps(thd, "steps");
DBUG_EXECUTE("where", print_where(conds, "original", QT_ORDINARY);); DBUG_EXECUTE("where", print_where(conds, "original", QT_ORDINARY););
@ -18404,10 +18444,13 @@ optimize_cond(JOIN *join, COND *conds,
ignore_on_conds, cond_equal, ignore_on_conds, cond_equal,
MY_TEST(flags & OPT_LINK_EQUAL_FIELDS)); MY_TEST(flags & OPT_LINK_EQUAL_FIELDS));
DBUG_EXECUTE("where",print_where(conds,"after equal_items", QT_ORDINARY);); DBUG_EXECUTE("where",print_where(conds,"after equal_items", QT_ORDINARY););
if (unlikely(thd->trace_started()))
{ {
Json_writer_object equal_prop_wrapper(thd); Json_writer_object equal_prop_wrapper(thd);
equal_prop_wrapper.add("transformation", "equality_propagation") equal_prop_wrapper.
.add("resulting_condition", conds); add("transformation", "equality_propagation").
add("resulting_condition", conds);
} }
/* change field = field to field = const for each found field = const */ /* change field = field to field = const for each found field = const */
@ -18417,20 +18460,24 @@ optimize_cond(JOIN *join, COND *conds,
Remove all and-levels where CONST item != CONST item Remove all and-levels where CONST item != CONST item
*/ */
DBUG_EXECUTE("where",print_where(conds,"after const change", QT_ORDINARY);); DBUG_EXECUTE("where",print_where(conds,"after const change", QT_ORDINARY););
if (unlikely(thd->trace_started()))
{ {
Json_writer_object const_prop_wrapper(thd); Json_writer_object const_prop_wrapper(thd);
const_prop_wrapper.add("transformation", "constant_propagation") const_prop_wrapper.
.add("resulting_condition", conds); add("transformation", "constant_propagation").
add("resulting_condition", conds);
} }
conds= conds->remove_eq_conds(thd, cond_value, true); conds= conds->remove_eq_conds(thd, cond_value, true);
if (conds && conds->type() == Item::COND_ITEM && if (conds && conds->type() == Item::COND_ITEM &&
((Item_cond*) conds)->functype() == Item_func::COND_AND_FUNC) ((Item_cond*) conds)->functype() == Item_func::COND_AND_FUNC)
*cond_equal= &((Item_cond_and*) conds)->m_cond_equal; *cond_equal= &((Item_cond_and*) conds)->m_cond_equal;
if (unlikely(thd->trace_started()))
{ {
Json_writer_object cond_removal_wrapper(thd); Json_writer_object cond_removal_wrapper(thd);
cond_removal_wrapper.add("transformation", "trivial_condition_removal") cond_removal_wrapper.
.add("resulting_condition", conds); add("transformation", "trivial_condition_removal").
add("resulting_condition", conds);
} }
DBUG_EXECUTE("info",print_where(conds,"after remove", QT_ORDINARY);); DBUG_EXECUTE("info",print_where(conds,"after remove", QT_ORDINARY););
} }
@ -30105,15 +30152,19 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table,
HA_POS_ERROR; HA_POS_ERROR;
if (is_best_covering && !is_covering) if (is_best_covering && !is_covering)
{ {
possible_key.add("chosen", false); if (unlikely(possible_key.trace_started()))
possible_key.add("cause", "covering index already found"); possible_key.
add("chosen", false).
add("cause", "covering index already found");
continue; continue;
} }
if (is_covering && refkey_select_limit < select_limit) if (is_covering && refkey_select_limit < select_limit)
{ {
possible_key.add("chosen", false); if (unlikely(possible_key.trace_started()))
possible_key.add("cause", "ref estimates better"); possible_key.
add("chosen", false).
add("cause", "ref estimates better");
continue; continue;
} }
if (table->opt_range_keys.is_set(nr)) if (table->opt_range_keys.is_set(nr))
@ -30153,8 +30204,9 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table,
} }
else else
{ {
possible_key.add("usable", false); possible_key.
possible_key.add("cause", "cost"); add("usable", false).
add("cause", "cost");
} }
} }
else else
@ -30168,13 +30220,15 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table,
{ {
if (keys.is_set(nr)) if (keys.is_set(nr))
{ {
possible_key.add("can_resolve_order", false); possible_key.
possible_key.add("cause", "order can not be resolved by key"); add("can_resolve_order", false).
add("cause", "order can not be resolved by key");
} }
else else
{ {
possible_key.add("can_resolve_order", false); possible_key.
possible_key.add("cause", "not usable index for the query"); add("can_resolve_order", false).
add("cause", "not usable index for the query");
} }
} }
} }

View File

@ -698,14 +698,15 @@ void print_keyuse_array_for_trace(THD *thd, DYNAMIC_ARRAY *keyuse_array)
{ {
keyuse_elem.add("index", keyuse->table->key_info[keyuse->key].name); keyuse_elem.add("index", keyuse->table->key_info[keyuse->key].name);
} }
keyuse_elem.add("field", (keyuse->keypart == FT_KEYPART) ? "<fulltext>": keyuse_elem.
(keyuse->is_for_hash_join() ? add("field", (keyuse->keypart == FT_KEYPART) ? "<fulltext>":
keyuse->table->field[keyuse->keypart] (keyuse->is_for_hash_join() ?
->field_name.str : keyuse->table->field[keyuse->keypart]
keyuse->table->key_info[keyuse->key] ->field_name.str :
.key_part[keyuse->keypart] keyuse->table->key_info[keyuse->key]
.field->field_name.str)); .key_part[keyuse->keypart]
keyuse_elem.add("equals",keyuse->val); .field->field_name.str)).
keyuse_elem.add("null_rejecting",keyuse->null_rejecting); add("equals",keyuse->val).
add("null_rejecting",keyuse->null_rejecting);
} }
} }

View File

@ -953,8 +953,10 @@ Item *Item_func_in::in_predicate_to_in_subs_transformer(THD *thd,
if (!length || length > tmp_table_max_key_length() || if (!length || length > tmp_table_max_key_length() ||
args[0]->cols() > tmp_table_max_key_parts()) args[0]->cols() > tmp_table_max_key_parts())
{ {
trace_conv.add("done", false); if (unlikely(trace_conv.trace_started()))
trace_conv.add("reason", "key is too long"); trace_conv.
add("done", false).
add("reason", "key is too long");
return this; return this;
} }
@ -962,15 +964,19 @@ Item *Item_func_in::in_predicate_to_in_subs_transformer(THD *thd,
{ {
if (!args[i]->const_item()) if (!args[i]->const_item())
{ {
trace_conv.add("done", false); if (unlikely(trace_conv.trace_started()))
trace_conv.add("reason", "non-constant element in the IN-list"); trace_conv.
add("done", false).
add("reason", "non-constant element in the IN-list");
return this; return this;
} }
if (cmp_row_types(args[i], args[0])) if (cmp_row_types(args[i], args[0]))
{ {
trace_conv.add("done", false); if (unlikely(trace_conv.trace_started()))
trace_conv.add("reason", "type mismatch"); trace_conv.
add("done", false).
add("reason", "type mismatch");
return this; return this;
} }
} }