diff options
author | Monty <monty@mariadb.org> | 2020-03-06 10:33:11 +0200 |
---|---|---|
committer | Monty <monty@mariadb.org> | 2020-03-09 13:49:06 +0200 |
commit | 940fcbe73bc0aad18bb77a45428126ff987b96c4 (patch) | |
tree | f432fa53c226da7c6934e5b6439358585f130fa4 /sql | |
parent | 1ad8693a6f6b44121651a0c7ccf80ae1f099744d (diff) | |
download | mariadb-git-940fcbe73bc0aad18bb77a45428126ff987b96c4.tar.gz |
Improved speed of optimizer trace
- Added unlikely() to optimize for not having optimizer trace enabled
- Made THD::trace_started() inline
- Added 'if (trace_enabled())' around some potentially expensive code
(not many found)
- Added ASSERT's to ensure we don't call expensive optimizer trace calls
if optimizer trace is not enabled
- Added length to Json_writer functions to speed up buffer writes
when optimizer trace is enabled.
- Changed LEX_CSTRING argument handling to not send full struct to writer
function on_add_str() functions now trusts length arguments
Diffstat (limited to 'sql')
-rw-r--r-- | sql/my_json_writer.cc | 89 | ||||
-rw-r--r-- | sql/my_json_writer.h | 52 | ||||
-rw-r--r-- | sql/opt_range.cc | 15 | ||||
-rw-r--r-- | sql/opt_subselect.cc | 30 | ||||
-rw-r--r-- | sql/opt_trace.cc | 33 | ||||
-rw-r--r-- | sql/sql_class.cc | 5 | ||||
-rw-r--r-- | sql/sql_class.h | 6 | ||||
-rw-r--r-- | sql/sql_select.cc | 43 | ||||
-rw-r--r-- | sql/sql_test.cc | 5 |
9 files changed, 176 insertions, 102 deletions
diff --git a/sql/my_json_writer.cc b/sql/my_json_writer.cc index 4200769b1dc..0c059d18a23 100644 --- a/sql/my_json_writer.cc +++ b/sql/my_json_writer.cc @@ -79,7 +79,8 @@ void Json_writer::end_array() Json_writer& Json_writer::add_member(const char *name) { - if (fmt_helper.on_add_member(name)) + size_t len= strlen(name); + if (fmt_helper.on_add_member(name, len)) return *this; // handled // assert that we are in an object @@ -87,7 +88,22 @@ Json_writer& Json_writer::add_member(const char *name) start_element(); output.append('"'); - output.append(name); + output.append(name, len); + output.append("\": ", 3); + return *this; +} + +Json_writer& Json_writer::add_member(const char *name, size_t len) +{ + if (fmt_helper.on_add_member(name, len)) + return *this; // handled + + // assert that we are in an object + DBUG_ASSERT(!element_started); + start_element(); + + output.append('"'); + output.append(name, len); output.append("\": "); return *this; } @@ -141,28 +157,31 @@ void Json_writer::add_ull(ulonglong val) void Json_writer::add_size(longlong val) { char buf[64]; + size_t len; if (val < 1024) - my_snprintf(buf, sizeof(buf), "%lld", val); + len= my_snprintf(buf, sizeof(buf), "%lld", val); else if (val < 1024*1024*16) { /* Values less than 16MB are specified in KB for precision */ - size_t len= my_snprintf(buf, sizeof(buf), "%lld", val/1024); + len= my_snprintf(buf, sizeof(buf), "%lld", val/1024); strcpy(buf + len, "Kb"); + len+= 2; } else { - size_t len= my_snprintf(buf, sizeof(buf), "%lld", val/(1024*1024)); + len= my_snprintf(buf, sizeof(buf), "%lld", val/(1024*1024)); strcpy(buf + len, "Mb"); + len+= 2; } - add_str(buf); + add_str(buf, len); } void Json_writer::add_double(double val) { char buf[64]; - my_snprintf(buf, sizeof(buf), "%lg", val); - add_unquoted_str(buf); + size_t len= my_snprintf(buf, sizeof(buf), "%lg", val); + add_unquoted_str(buf, len); } @@ -174,32 +193,46 @@ void Json_writer::add_bool(bool val) void Json_writer::add_null() { - add_unquoted_str("null"); + add_unquoted_str("null", (size_t) 4); } void Json_writer::add_unquoted_str(const char* str) { - if (fmt_helper.on_add_str(str, 0)) + size_t len= strlen(str); + if (fmt_helper.on_add_str(str, len)) + return; + + if (!element_started) + start_element(); + + output.append(str, len); + element_started= false; +} + +void Json_writer::add_unquoted_str(const char* str, size_t len) +{ + if (fmt_helper.on_add_str(str, len)) return; if (!element_started) start_element(); - output.append(str); + output.append(str, len); element_started= false; } void Json_writer::add_str(const char *str) { - if (fmt_helper.on_add_str(str, 0)) + size_t len= strlen(str); + if (fmt_helper.on_add_str(str, len)) return; if (!element_started) start_element(); output.append('"'); - output.append(str); + output.append(str, len); output.append('"'); element_started= false; } @@ -230,20 +263,20 @@ void Json_writer::add_str(const String &str) Json_writer_object::Json_writer_object(THD *thd) : Json_writer_struct(thd) { - if (my_writer) + if (unlikely(my_writer)) my_writer->start_object(); } Json_writer_object::Json_writer_object(THD* thd, const char *str) : Json_writer_struct(thd) { - if (my_writer) + if (unlikely(my_writer)) my_writer->add_member(str).start_object(); } Json_writer_object::~Json_writer_object() { - if (!closed && my_writer) + if (my_writer && !closed) my_writer->end_object(); closed= TRUE; } @@ -251,20 +284,20 @@ Json_writer_object::~Json_writer_object() Json_writer_array::Json_writer_array(THD *thd) : Json_writer_struct(thd) { - if (my_writer) + if (unlikely(my_writer)) my_writer->start_array(); } Json_writer_array::Json_writer_array(THD *thd, const char *str) : Json_writer_struct(thd) { - if (my_writer) + if (unlikely(my_writer)) my_writer->add_member(str).start_array(); } Json_writer_array::~Json_writer_array() { - if (!closed && my_writer) + if (unlikely(my_writer && !closed)) { my_writer->end_array(); closed= TRUE; @@ -281,7 +314,8 @@ Json_writer_temp_disable::~Json_writer_temp_disable() thd->opt_trace.enable_tracing_if_required(); } -bool Single_line_formatting_helper::on_add_member(const char *name) +bool Single_line_formatting_helper::on_add_member(const char *name, + size_t len) { DBUG_ASSERT(state== INACTIVE || state == DISABLED); if (state != DISABLED) @@ -290,7 +324,6 @@ bool Single_line_formatting_helper::on_add_member(const char *name) buf_ptr= buffer; //append member name to the array - size_t len= strlen(name); if (len < MAX_LINE_LEN) { memcpy(buf_ptr, name, len); @@ -344,12 +377,10 @@ void Single_line_formatting_helper::on_start_object() bool Single_line_formatting_helper::on_add_str(const char *str, - size_t num_bytes) + size_t len) { if (state == IN_ARRAY) { - size_t len= num_bytes ? num_bytes : strlen(str); - // New length will be: // "$string", // quote + quote + comma + space = 4 @@ -425,9 +456,11 @@ void Single_line_formatting_helper::disable_and_flush() while (ptr < buf_ptr) { char *str= ptr; + size_t len= strlen(str); + if (nr == 0) { - owner->add_member(str); + owner->add_member(str, len); if (start_array) owner->start_array(); } @@ -435,13 +468,11 @@ void Single_line_formatting_helper::disable_and_flush() { //if (nr == 1) // owner->start_array(); - owner->add_str(str); + owner->add_str(str, len); } nr++; - while (*ptr!=0) - ptr++; - ptr++; + ptr+= len+1; } buf_ptr= buffer; state= INACTIVE; diff --git a/sql/my_json_writer.h b/sql/my_json_writer.h index f1f1be70bb0..f7ae58d9bc8 100644 --- a/sql/my_json_writer.h +++ b/sql/my_json_writer.h @@ -86,7 +86,7 @@ public: void init(Json_writer *owner_arg) { owner= owner_arg; } - bool on_add_member(const char *name); + bool on_add_member(const char *name, size_t len); bool on_start_array(); bool on_end_array(); @@ -184,6 +184,7 @@ class Json_writer public: /* Add a member. We must be in an object. */ Json_writer& add_member(const char *name); + Json_writer& add_member(const char *name, size_t len); /* Add atomic values */ void add_str(const char* val); @@ -202,6 +203,7 @@ public: private: void add_unquoted_str(const char* val); + void add_unquoted_str(const char* val, size_t len); public: /* Start a child object */ void start_object(); @@ -254,63 +256,63 @@ public: void init(Json_writer *my_writer) { writer= my_writer; } void add_str(const char* val) { - if (writer) + if (unlikely(writer)) writer->add_str(val); } void add_str(const char* val, size_t length) { - if (writer) + if (unlikely(writer)) writer->add_str(val, length); } void add_str(const String &str) { - if (writer) - writer->add_str(str); + if (unlikely(writer)) + writer->add_str(str.ptr(), str.length()); } - void add_str(LEX_CSTRING str) + void add_str(const LEX_CSTRING &str) { - if (writer) - writer->add_str(str.str); + if (unlikely(writer)) + writer->add_str(str.str, str.length); } void add_str(Item *item) { - if (writer) + if (unlikely(writer)) writer->add_str(item); } void add_ll(longlong val) { - if (writer) + if (unlikely(writer)) writer->add_ll(val); } void add_size(longlong val) { - if (writer) + if (unlikely(writer)) writer->add_size(val); } void add_double(double val) { - if (writer) + if (unlikely(writer)) writer->add_double(val); } void add_bool(bool val) { - if (writer) + if (unlikely(writer)) writer->add_bool(val); } void add_null() { - if (writer) + if (unlikely(writer)) writer->add_null(); } void add_table_name(const JOIN_TAB *tab) { - if (writer) + if (unlikely(writer)) writer->add_table_name(tab); } void add_table_name(const TABLE* table) { - if (writer) + if (unlikely(writer)) writer->add_table_name(table); } }; @@ -333,6 +335,10 @@ public: context.init(my_writer); closed= false; } + bool trace_started() + { + return my_writer != 0; + } }; @@ -349,7 +355,7 @@ class Json_writer_object : public Json_writer_struct private: void add_member(const char *name) { - if (my_writer) + if (unlikely(my_writer)) my_writer->add_member(name); } public: @@ -406,11 +412,11 @@ public: context.add_str(value, num_bytes); return *this; } - Json_writer_object& add(const char *name, LEX_CSTRING value) + Json_writer_object& add(const char *name, const LEX_CSTRING &value) { DBUG_ASSERT(!closed); add_member(name); - context.add_str(value.str); + context.add_str(value.str, value.length); return *this; } Json_writer_object& add(const char *name, Item *value) @@ -454,7 +460,7 @@ public: void end() { DBUG_ASSERT(!closed); - if (my_writer) + if (unlikely(my_writer)) my_writer->end_object(); closed= TRUE; } @@ -478,7 +484,7 @@ public: void end() { DBUG_ASSERT(!closed); - if (my_writer) + if (unlikely(my_writer)) my_writer->end_array(); closed= TRUE; } @@ -527,10 +533,10 @@ public: context.add_str(value, num_bytes); return *this; } - Json_writer_array& add(LEX_CSTRING value) + Json_writer_array& add(const LEX_CSTRING &value) { DBUG_ASSERT(!closed); - context.add_str(value.str); + context.add_str(value.str, value.length); return *this; } Json_writer_array& add(Item *value) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index bff770fdc00..a1982e246a7 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -2258,6 +2258,7 @@ public: void TRP_RANGE::trace_basic_info(PARAM *param, Json_writer_object *trace_object) const { + DBUG_ASSERT(trace_object->trace_started()); DBUG_ASSERT(param->using_real_indexes); const uint keynr_in_table= param->real_keynr[key_idx]; @@ -2322,6 +2323,7 @@ void TRP_ROR_UNION::trace_basic_info(PARAM *param, Json_writer_object *trace_object) const { THD *thd= param->thd; + DBUG_ASSERT(trace_object->trace_started()); trace_object->add("type", "index_roworder_union"); Json_writer_array smth_trace(thd, "union_of"); for (TABLE_READ_PLAN **current= first_ror; current != last_ror; current++) @@ -2357,6 +2359,7 @@ void TRP_INDEX_INTERSECT::trace_basic_info(PARAM *param, Json_writer_object *trace_object) const { THD *thd= param->thd; + DBUG_ASSERT(trace_object->trace_started()); trace_object->add("type", "index_sort_intersect"); Json_writer_array smth_trace(thd, "index_sort_intersect_of"); for (TRP_RANGE **current= range_scans; current != range_scans_end; @@ -2390,6 +2393,7 @@ void TRP_INDEX_MERGE::trace_basic_info(PARAM *param, Json_writer_object *trace_object) const { THD *thd= param->thd; + DBUG_ASSERT(trace_object->trace_started()); trace_object->add("type", "index_merge"); Json_writer_array smth_trace(thd, "index_merge_of"); for (TRP_RANGE **current= range_scans; current != range_scans_end; current++) @@ -2458,6 +2462,8 @@ void TRP_GROUP_MIN_MAX::trace_basic_info(PARAM *param, Json_writer_object *trace_object) const { THD *thd= param->thd; + DBUG_ASSERT(trace_object->trace_started()); + trace_object->add("type", "index_group").add("index", index_info->name); if (min_max_arg_part) @@ -2833,7 +2839,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, { { Json_writer_array trace_range_summary(thd, - "setup_range_conditions"); + "setup_range_conditions"); tree= cond->get_mm_tree(¶m, &cond); } if (tree) @@ -5596,6 +5602,8 @@ ha_rows get_table_cardinality_for_index_intersect(TABLE *table) static void print_keyparts(THD *thd, KEY *key, uint key_parts) { + DBUG_ASSERT(thd->trace_started()); + KEY_PART_INFO *part= key->key_part; Json_writer_array keyparts= Json_writer_array(thd, "keyparts"); for(uint i= 0; i < key_parts; i++, part++) @@ -6385,6 +6393,8 @@ void TRP_ROR_INTERSECT::trace_basic_info(PARAM *param, Json_writer_object *trace_object) const { THD *thd= param->thd; + DBUG_ASSERT(trace_object->trace_started()); + trace_object->add("type", "index_roworder_intersect"); trace_object->add("rows", records); trace_object->add("cost", read_cost); @@ -7424,10 +7434,12 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree, { trace_idx.add("chosen", false); if (found_records == HA_POS_ERROR) + { if (key->type == SEL_ARG::Type::MAYBE_KEY) trace_idx.add("cause", "depends on unread values"); else trace_idx.add("cause", "unknown"); + } else trace_idx.add("cause", "cost"); } @@ -15829,6 +15841,7 @@ static void trace_ranges(Json_writer_array *range_trace, sel_arg_range_seq_next, 0, 0}; KEY *keyinfo= param->table->key_info + param->real_keynr[idx]; uint n_key_parts= param->table->actual_n_key_parts(keyinfo); + DBUG_ASSERT(range_trace->trace_started()); seq.keyno= idx; seq.real_keyno= param->real_keynr[idx]; seq.param= param; diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 23767bfbc16..dbb71264777 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -3050,12 +3050,13 @@ bool Sj_materialization_picker::check_qep(JOIN *join, } else { - Json_writer_object trace(join->thd); - trace.add("strategy", "SJ-Materialization"); /* This is SJ-Materialization with lookups */ Cost_estimate prefix_cost; signed int first_tab= (int)idx - mat_info->tables; double prefix_rec_count; + Json_writer_object trace(join->thd); + trace.add("strategy", "SJ-Materialization"); + if (first_tab < (int)join->const_tables) { prefix_cost.reset(); @@ -3084,7 +3085,7 @@ bool Sj_materialization_picker::check_qep(JOIN *join, *record_count= prefix_rec_count; *handled_fanout= new_join_tab->emb_sj_nest->sj_inner_tables; *strategy= SJ_OPT_MATERIALIZE; - if (unlikely(join->thd->trace_started())) + if (unlikely(trace.trace_started())) { trace.add("records", *record_count); trace.add("read_time", *read_time); @@ -3166,7 +3167,7 @@ bool Sj_materialization_picker::check_qep(JOIN *join, */ *record_count= prefix_rec_count; *handled_fanout= mat_nest->sj_inner_tables; - if (unlikely(join->thd->trace_started())) + if (unlikely(trace.trace_started())) { trace.add("records", *record_count); trace.add("read_time", *read_time); @@ -3266,7 +3267,7 @@ bool LooseScan_picker::check_qep(JOIN *join, */ *strategy= SJ_OPT_LOOSE_SCAN; *handled_fanout= first->table->emb_sj_nest->sj_inner_tables; - if (unlikely(join->thd->trace_started())) + if (unlikely(trace.trace_started())) { trace.add("records", *record_count); trace.add("read_time", *read_time); @@ -3384,7 +3385,7 @@ bool Firstmatch_picker::check_qep(JOIN *join, *handled_fanout= firstmatch_need_tables; /* *record_count and *read_time were set by the above call */ *strategy= SJ_OPT_FIRST_MATCH; - if (unlikely(join->thd->trace_started())) + if (unlikely(trace.trace_started())) { trace.add("records", *record_count); trace.add("read_time", *read_time); @@ -3469,6 +3470,7 @@ bool Duplicate_weedout_picker::check_qep(JOIN *join, uint temptable_rec_size; Json_writer_object trace(join->thd); trace.add("strategy", "DuplicateWeedout"); + if (first_tab == join->const_tables) { prefix_rec_count= 1.0; @@ -3529,7 +3531,7 @@ bool Duplicate_weedout_picker::check_qep(JOIN *join, *record_count= prefix_rec_count * sj_outer_fanout; *handled_fanout= dups_removed_fanout; *strategy= SJ_OPT_DUPS_WEEDOUT; - if (unlikely(join->thd->trace_started())) + if (unlikely(trace.trace_started())) { trace.add("records", *record_count); trace.add("read_time", *read_time); @@ -3727,18 +3729,20 @@ static void recalculate_prefix_record_count(JOIN *join, uint start, uint end) void fix_semijoin_strategies_for_picked_join_order(JOIN *join) { - uint table_count=join->table_count; - uint tablenr; - table_map remaining_tables= 0; - table_map handled_tabs= 0; join->sjm_lookup_tables= 0; join->sjm_scan_tables= 0; - THD *thd= join->thd; if (!join->select_lex->sj_nests.elements) return; + + THD *thd= join->thd; + uint table_count=join->table_count; + uint tablenr; + table_map remaining_tables= 0; + table_map handled_tabs= 0; Json_writer_object trace_wrapper(thd); Json_writer_array trace_semijoin_strategies(thd, - "fix_semijoin_strategies_for_picked_join_order"); + "fix_semijoin_strategies_for_picked_join_order"); + for (tablenr= table_count - 1 ; tablenr != join->const_tables - 1; tablenr--) { POSITION *pos= join->best_positions + tablenr; diff --git a/sql/opt_trace.cc b/sql/opt_trace.cc index 7c82ba829bc..50274f06fbc 100644 --- a/sql/opt_trace.cc +++ b/sql/opt_trace.cc @@ -105,8 +105,8 @@ void opt_trace_print_expanded_query(THD *thd, SELECT_LEX *select_lex, Json_writer_object *writer) { - if (!thd->trace_started()) - return; + DBUG_ASSERT(thd->trace_started()); + StringBuffer<1024> str(system_charset_info); ulonglong save_option_bits= thd->variables.option_bits; thd->variables.option_bits &= ~OPTION_QUOTE_SHOW_CREATE; @@ -195,12 +195,11 @@ void opt_trace_disable_if_no_stored_proc_func_access(THD *thd, sp_head *sp) { if (likely(!(thd->variables.optimizer_trace & Opt_trace_context::FLAG_ENABLED)) || - thd->system_thread) + thd->system_thread || + !thd->trace_started()) return; Opt_trace_context *const trace= &thd->opt_trace; - if (!thd->trace_started()) - return; bool full_access; Security_context *const backup_thd_sctx= thd->security_context(); thd->set_security_context(&thd->main_security_ctx); @@ -229,13 +228,12 @@ void opt_trace_disable_if_no_stored_proc_func_access(THD *thd, sp_head *sp) void opt_trace_disable_if_no_tables_access(THD *thd, TABLE_LIST *tbl) { if (likely(!(thd->variables.optimizer_trace & - Opt_trace_context::FLAG_ENABLED)) || thd->system_thread) - return; - Opt_trace_context *const trace= &thd->opt_trace; - - if (!thd->trace_started()) + Opt_trace_context::FLAG_ENABLED)) || + thd->system_thread || + !thd->trace_started()) return; + Opt_trace_context *const trace= &thd->opt_trace; Security_context *const backup_thd_sctx= thd->security_context(); thd->set_security_context(&thd->main_security_ctx); const TABLE_LIST *const first_not_own_table= thd->lex->first_not_own_table(); @@ -290,12 +288,11 @@ void opt_trace_disable_if_no_view_access(THD *thd, TABLE_LIST *view, if (likely(!(thd->variables.optimizer_trace & Opt_trace_context::FLAG_ENABLED)) || - thd->system_thread) - return; - Opt_trace_context *const trace= &thd->opt_trace; - if (!thd->trace_started()) + thd->system_thread || + !thd->trace_started()) return; + Opt_trace_context *const trace= &thd->opt_trace; Security_context *const backup_table_sctx= view->security_ctx; Security_context *const backup_thd_sctx= thd->security_context(); const GRANT_INFO backup_grant_info= view->grant; @@ -592,6 +589,7 @@ void Opt_trace_stmt::set_allowed_mem_size(size_t mem_size) void Json_writer::add_table_name(const JOIN_TAB *tab) { + DBUG_ASSERT(tab->join->thd->trace_started()); if (tab != NULL) { char table_name_buffer[SAFE_NAME_LEN]; @@ -630,6 +628,7 @@ void Json_writer::add_table_name(const TABLE *table) void add_table_scan_values_to_trace(THD *thd, JOIN_TAB *tab) { + DBUG_ASSERT(thd->trace_started()); Json_writer_object table_records(thd); table_records.add_table_name(tab); Json_writer_object table_rec(thd, "table_scan"); @@ -655,6 +654,8 @@ void add_table_scan_values_to_trace(THD *thd, JOIN_TAB *tab) void trace_plan_prefix(JOIN *join, uint idx, table_map join_tables) { THD *const thd= join->thd; + DBUG_ASSERT(thd->trace_started()); + Json_writer_array plan_prefix(thd, "plan_prefix"); for (uint i= 0; i < idx; i++) { @@ -679,6 +680,8 @@ void trace_plan_prefix(JOIN *join, uint idx, table_map join_tables) void print_final_join_order(JOIN *join) { + DBUG_ASSERT(join->thd->trace_started()); + Json_writer_object join_order(join->thd); Json_writer_array best_order(join->thd, "best_join_order"); JOIN_TAB *j; @@ -692,6 +695,8 @@ void print_final_join_order(JOIN *join) void print_best_access_for_table(THD *thd, POSITION *pos, enum join_type type) { + DBUG_ASSERT(thd->trace_started()); + Json_writer_object trace_best_access(thd, "chosen_access_method"); trace_best_access.add("type", type == JT_ALL ? "scan" : join_type_str[type]); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 84e18e71a80..ca33a2a8f12 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2205,11 +2205,6 @@ void THD::reset_globals() net.thd= 0; } -bool THD::trace_started() -{ - return opt_trace.is_started(); -} - /* Cleanup after query. diff --git a/sql/sql_class.h b/sql/sql_class.h index 36cb42c6314..2c7e911f808 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -3274,7 +3274,10 @@ public: void reset_for_reuse(); bool store_globals(); void reset_globals(); - bool trace_started(); + bool trace_started() + { + return opt_trace.is_started(); + } #ifdef SIGNAL_WITH_VIO_CLOSE inline void set_active_vio(Vio* vio) { @@ -5003,6 +5006,7 @@ public: Item *sp_fix_func_item(Item **it_addr); Item *sp_prepare_func_item(Item **it_addr, uint cols= 1); bool sp_eval_expr(Field *result_field, Item **expr_item_ptr); + }; /** A short cut for thd->get_stmt_da()->set_ok_status(). */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index decbdd59447..53f990ffd1f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -353,8 +353,10 @@ bool dbug_user_var_equals_int(THD *thd, const char *name, int value) static void trace_table_dependencies(THD *thd, JOIN_TAB *join_tabs, uint table_count) { + DBUG_ASSERT(thd->trace_started()); Json_writer_object trace_wrapper(thd); Json_writer_array trace_dep(thd, "table_dependencies"); + for (uint i= 0; i < table_count; i++) { TABLE_LIST *table_ref= join_tabs[i].tab_list; @@ -1469,6 +1471,7 @@ JOIN::prepare(TABLE_LIST *tables_init, } } + if (thd->trace_started()) { Json_writer_object trace_wrapper(thd); opt_trace_print_expanded_query(thd, select_lex, &trace_wrapper); @@ -5352,6 +5355,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list, { Json_writer_object rows_estimation_wrapper(thd); Json_writer_array rows_estimation(thd, "rows_estimation"); + for (s=stat ; s < stat_end ; s++) { s->startup_cost= 0; @@ -5496,10 +5500,16 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list, if (select) delete select; else - add_table_scan_values_to_trace(thd, s); + { + if (thd->trace_started()) + add_table_scan_values_to_trace(thd, s); + } } else - add_table_scan_values_to_trace(thd, s); + { + if (thd->trace_started()) + add_table_scan_values_to_trace(thd, s); + } } } @@ -7402,7 +7412,7 @@ best_access_path(JOIN *join, Json_writer_object trace_access_idx(thd); /* - ft-keys require special treatment + full text keys require special treatment */ if (ft_key) { @@ -7414,7 +7424,7 @@ best_access_path(JOIN *join, records= 1.0; type= JT_FT; trace_access_idx.add("access_type", join_type_str[type]) - .add("index", keyinfo->name); + .add("full-text index", keyinfo->name); } else { @@ -11866,18 +11876,21 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) i++; } - trace_attached_comp.end(); - Json_writer_array trace_attached_summary(thd, - "attached_conditions_summary"); - for (tab= first_depth_first_tab(join); tab; - tab= next_depth_first_tab(join, tab)) + if (unlikely(thd->trace_started())) { - if (!tab->table) - continue; - Item *const cond = tab->select_cond; - Json_writer_object trace_one_table(thd); - trace_one_table.add_table_name(tab); - trace_one_table.add("attached", cond); + trace_attached_comp.end(); + Json_writer_array trace_attached_summary(thd, + "attached_conditions_summary"); + for (tab= first_depth_first_tab(join); tab; + tab= next_depth_first_tab(join, tab)) + { + if (!tab->table) + continue; + Item *const cond = tab->select_cond; + Json_writer_object trace_one_table(thd); + trace_one_table.add_table_name(tab); + trace_one_table.add("attached", cond); + } } } DBUG_RETURN(0); diff --git a/sql/sql_test.cc b/sql/sql_test.cc index 68d30d5fecb..a3506687a72 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -658,9 +658,12 @@ Memory allocated by threads: %s\n", void print_keyuse_array_for_trace(THD *thd, DYNAMIC_ARRAY *keyuse_array) { + DBUG_ASSERT(thd->trace_started()); + Json_writer_object wrapper(thd); Json_writer_array trace_key_uses(thd, "ref_optimizer_key_uses"); - for(uint i=0; i < keyuse_array->elements; i++) + + for (uint i=0; i < keyuse_array->elements; i++) { KEYUSE *keyuse= (KEYUSE*)dynamic_array_ptr(keyuse_array, i); Json_writer_object keyuse_elem(thd); |