summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2020-03-06 10:33:11 +0200
committerMonty <monty@mariadb.org>2020-03-09 13:49:06 +0200
commit940fcbe73bc0aad18bb77a45428126ff987b96c4 (patch)
treef432fa53c226da7c6934e5b6439358585f130fa4 /sql
parent1ad8693a6f6b44121651a0c7ccf80ae1f099744d (diff)
downloadmariadb-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.cc89
-rw-r--r--sql/my_json_writer.h52
-rw-r--r--sql/opt_range.cc15
-rw-r--r--sql/opt_subselect.cc30
-rw-r--r--sql/opt_trace.cc33
-rw-r--r--sql/sql_class.cc5
-rw-r--r--sql/sql_class.h6
-rw-r--r--sql/sql_select.cc43
-rw-r--r--sql/sql_test.cc5
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(&param, &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);