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
This commit is contained in:
parent
1ad8693a6f
commit
940fcbe73b
@ -79,7 +79,8 @@ void Json_writer::end_array()
|
|||||||
|
|
||||||
Json_writer& Json_writer::add_member(const char *name)
|
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
|
return *this; // handled
|
||||||
|
|
||||||
// assert that we are in an object
|
// assert that we are in an object
|
||||||
@ -87,7 +88,22 @@ Json_writer& Json_writer::add_member(const char *name)
|
|||||||
start_element();
|
start_element();
|
||||||
|
|
||||||
output.append('"');
|
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("\": ");
|
output.append("\": ");
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -141,28 +157,31 @@ void Json_writer::add_ull(ulonglong val)
|
|||||||
void Json_writer::add_size(longlong val)
|
void Json_writer::add_size(longlong val)
|
||||||
{
|
{
|
||||||
char buf[64];
|
char buf[64];
|
||||||
|
size_t len;
|
||||||
if (val < 1024)
|
if (val < 1024)
|
||||||
my_snprintf(buf, sizeof(buf), "%lld", val);
|
len= my_snprintf(buf, sizeof(buf), "%lld", val);
|
||||||
else if (val < 1024*1024*16)
|
else if (val < 1024*1024*16)
|
||||||
{
|
{
|
||||||
/* Values less than 16MB are specified in KB for precision */
|
/* 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");
|
strcpy(buf + len, "Kb");
|
||||||
|
len+= 2;
|
||||||
}
|
}
|
||||||
else
|
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");
|
strcpy(buf + len, "Mb");
|
||||||
|
len+= 2;
|
||||||
}
|
}
|
||||||
add_str(buf);
|
add_str(buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Json_writer::add_double(double val)
|
void Json_writer::add_double(double val)
|
||||||
{
|
{
|
||||||
char buf[64];
|
char buf[64];
|
||||||
my_snprintf(buf, sizeof(buf), "%lg", val);
|
size_t len= my_snprintf(buf, sizeof(buf), "%lg", val);
|
||||||
add_unquoted_str(buf);
|
add_unquoted_str(buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -174,32 +193,46 @@ void Json_writer::add_bool(bool val)
|
|||||||
|
|
||||||
void Json_writer::add_null()
|
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)
|
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;
|
return;
|
||||||
|
|
||||||
if (!element_started)
|
if (!element_started)
|
||||||
start_element();
|
start_element();
|
||||||
|
|
||||||
output.append(str);
|
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, len);
|
||||||
element_started= false;
|
element_started= false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Json_writer::add_str(const char *str)
|
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;
|
return;
|
||||||
|
|
||||||
if (!element_started)
|
if (!element_started)
|
||||||
start_element();
|
start_element();
|
||||||
|
|
||||||
output.append('"');
|
output.append('"');
|
||||||
output.append(str);
|
output.append(str, len);
|
||||||
output.append('"');
|
output.append('"');
|
||||||
element_started= false;
|
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_object::Json_writer_object(THD *thd) :
|
||||||
Json_writer_struct(thd)
|
Json_writer_struct(thd)
|
||||||
{
|
{
|
||||||
if (my_writer)
|
if (unlikely(my_writer))
|
||||||
my_writer->start_object();
|
my_writer->start_object();
|
||||||
}
|
}
|
||||||
|
|
||||||
Json_writer_object::Json_writer_object(THD* thd, const char *str) :
|
Json_writer_object::Json_writer_object(THD* thd, const char *str) :
|
||||||
Json_writer_struct(thd)
|
Json_writer_struct(thd)
|
||||||
{
|
{
|
||||||
if (my_writer)
|
if (unlikely(my_writer))
|
||||||
my_writer->add_member(str).start_object();
|
my_writer->add_member(str).start_object();
|
||||||
}
|
}
|
||||||
|
|
||||||
Json_writer_object::~Json_writer_object()
|
Json_writer_object::~Json_writer_object()
|
||||||
{
|
{
|
||||||
if (!closed && my_writer)
|
if (my_writer && !closed)
|
||||||
my_writer->end_object();
|
my_writer->end_object();
|
||||||
closed= TRUE;
|
closed= TRUE;
|
||||||
}
|
}
|
||||||
@ -251,20 +284,20 @@ Json_writer_object::~Json_writer_object()
|
|||||||
Json_writer_array::Json_writer_array(THD *thd) :
|
Json_writer_array::Json_writer_array(THD *thd) :
|
||||||
Json_writer_struct(thd)
|
Json_writer_struct(thd)
|
||||||
{
|
{
|
||||||
if (my_writer)
|
if (unlikely(my_writer))
|
||||||
my_writer->start_array();
|
my_writer->start_array();
|
||||||
}
|
}
|
||||||
|
|
||||||
Json_writer_array::Json_writer_array(THD *thd, const char *str) :
|
Json_writer_array::Json_writer_array(THD *thd, const char *str) :
|
||||||
Json_writer_struct(thd)
|
Json_writer_struct(thd)
|
||||||
{
|
{
|
||||||
if (my_writer)
|
if (unlikely(my_writer))
|
||||||
my_writer->add_member(str).start_array();
|
my_writer->add_member(str).start_array();
|
||||||
|
|
||||||
}
|
}
|
||||||
Json_writer_array::~Json_writer_array()
|
Json_writer_array::~Json_writer_array()
|
||||||
{
|
{
|
||||||
if (!closed && my_writer)
|
if (unlikely(my_writer && !closed))
|
||||||
{
|
{
|
||||||
my_writer->end_array();
|
my_writer->end_array();
|
||||||
closed= TRUE;
|
closed= TRUE;
|
||||||
@ -281,7 +314,8 @@ Json_writer_temp_disable::~Json_writer_temp_disable()
|
|||||||
thd->opt_trace.enable_tracing_if_required();
|
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);
|
DBUG_ASSERT(state== INACTIVE || state == DISABLED);
|
||||||
if (state != DISABLED)
|
if (state != DISABLED)
|
||||||
@ -290,7 +324,6 @@ bool Single_line_formatting_helper::on_add_member(const char *name)
|
|||||||
buf_ptr= buffer;
|
buf_ptr= buffer;
|
||||||
|
|
||||||
//append member name to the array
|
//append member name to the array
|
||||||
size_t len= strlen(name);
|
|
||||||
if (len < MAX_LINE_LEN)
|
if (len < MAX_LINE_LEN)
|
||||||
{
|
{
|
||||||
memcpy(buf_ptr, name, 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,
|
bool Single_line_formatting_helper::on_add_str(const char *str,
|
||||||
size_t num_bytes)
|
size_t len)
|
||||||
{
|
{
|
||||||
if (state == IN_ARRAY)
|
if (state == IN_ARRAY)
|
||||||
{
|
{
|
||||||
size_t len= num_bytes ? num_bytes : strlen(str);
|
|
||||||
|
|
||||||
// New length will be:
|
// New length will be:
|
||||||
// "$string",
|
// "$string",
|
||||||
// quote + quote + comma + space = 4
|
// quote + quote + comma + space = 4
|
||||||
@ -425,9 +456,11 @@ void Single_line_formatting_helper::disable_and_flush()
|
|||||||
while (ptr < buf_ptr)
|
while (ptr < buf_ptr)
|
||||||
{
|
{
|
||||||
char *str= ptr;
|
char *str= ptr;
|
||||||
|
size_t len= strlen(str);
|
||||||
|
|
||||||
if (nr == 0)
|
if (nr == 0)
|
||||||
{
|
{
|
||||||
owner->add_member(str);
|
owner->add_member(str, len);
|
||||||
if (start_array)
|
if (start_array)
|
||||||
owner->start_array();
|
owner->start_array();
|
||||||
}
|
}
|
||||||
@ -435,13 +468,11 @@ void Single_line_formatting_helper::disable_and_flush()
|
|||||||
{
|
{
|
||||||
//if (nr == 1)
|
//if (nr == 1)
|
||||||
// owner->start_array();
|
// owner->start_array();
|
||||||
owner->add_str(str);
|
owner->add_str(str, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
nr++;
|
nr++;
|
||||||
while (*ptr!=0)
|
ptr+= len+1;
|
||||||
ptr++;
|
|
||||||
ptr++;
|
|
||||||
}
|
}
|
||||||
buf_ptr= buffer;
|
buf_ptr= buffer;
|
||||||
state= INACTIVE;
|
state= INACTIVE;
|
||||||
|
@ -86,7 +86,7 @@ public:
|
|||||||
|
|
||||||
void init(Json_writer *owner_arg) { owner= owner_arg; }
|
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_start_array();
|
||||||
bool on_end_array();
|
bool on_end_array();
|
||||||
@ -184,6 +184,7 @@ class Json_writer
|
|||||||
public:
|
public:
|
||||||
/* Add a member. We must be in an object. */
|
/* Add a member. We must be in an object. */
|
||||||
Json_writer& add_member(const char *name);
|
Json_writer& add_member(const char *name);
|
||||||
|
Json_writer& add_member(const char *name, size_t len);
|
||||||
|
|
||||||
/* Add atomic values */
|
/* Add atomic values */
|
||||||
void add_str(const char* val);
|
void add_str(const char* val);
|
||||||
@ -202,6 +203,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void add_unquoted_str(const char* val);
|
void add_unquoted_str(const char* val);
|
||||||
|
void add_unquoted_str(const char* val, size_t len);
|
||||||
public:
|
public:
|
||||||
/* Start a child object */
|
/* Start a child object */
|
||||||
void start_object();
|
void start_object();
|
||||||
@ -254,63 +256,63 @@ public:
|
|||||||
void init(Json_writer *my_writer) { writer= my_writer; }
|
void init(Json_writer *my_writer) { writer= my_writer; }
|
||||||
void add_str(const char* val)
|
void add_str(const char* val)
|
||||||
{
|
{
|
||||||
if (writer)
|
if (unlikely(writer))
|
||||||
writer->add_str(val);
|
writer->add_str(val);
|
||||||
}
|
}
|
||||||
void add_str(const char* val, size_t length)
|
void add_str(const char* val, size_t length)
|
||||||
{
|
{
|
||||||
if (writer)
|
if (unlikely(writer))
|
||||||
writer->add_str(val, length);
|
writer->add_str(val, length);
|
||||||
}
|
}
|
||||||
void add_str(const String &str)
|
void add_str(const String &str)
|
||||||
{
|
{
|
||||||
if (writer)
|
if (unlikely(writer))
|
||||||
writer->add_str(str);
|
writer->add_str(str.ptr(), str.length());
|
||||||
}
|
}
|
||||||
void add_str(LEX_CSTRING str)
|
void add_str(const LEX_CSTRING &str)
|
||||||
{
|
{
|
||||||
if (writer)
|
if (unlikely(writer))
|
||||||
writer->add_str(str.str);
|
writer->add_str(str.str, str.length);
|
||||||
}
|
}
|
||||||
void add_str(Item *item)
|
void add_str(Item *item)
|
||||||
{
|
{
|
||||||
if (writer)
|
if (unlikely(writer))
|
||||||
writer->add_str(item);
|
writer->add_str(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_ll(longlong val)
|
void add_ll(longlong val)
|
||||||
{
|
{
|
||||||
if (writer)
|
if (unlikely(writer))
|
||||||
writer->add_ll(val);
|
writer->add_ll(val);
|
||||||
}
|
}
|
||||||
void add_size(longlong val)
|
void add_size(longlong val)
|
||||||
{
|
{
|
||||||
if (writer)
|
if (unlikely(writer))
|
||||||
writer->add_size(val);
|
writer->add_size(val);
|
||||||
}
|
}
|
||||||
void add_double(double val)
|
void add_double(double val)
|
||||||
{
|
{
|
||||||
if (writer)
|
if (unlikely(writer))
|
||||||
writer->add_double(val);
|
writer->add_double(val);
|
||||||
}
|
}
|
||||||
void add_bool(bool val)
|
void add_bool(bool val)
|
||||||
{
|
{
|
||||||
if (writer)
|
if (unlikely(writer))
|
||||||
writer->add_bool(val);
|
writer->add_bool(val);
|
||||||
}
|
}
|
||||||
void add_null()
|
void add_null()
|
||||||
{
|
{
|
||||||
if (writer)
|
if (unlikely(writer))
|
||||||
writer->add_null();
|
writer->add_null();
|
||||||
}
|
}
|
||||||
void add_table_name(const JOIN_TAB *tab)
|
void add_table_name(const JOIN_TAB *tab)
|
||||||
{
|
{
|
||||||
if (writer)
|
if (unlikely(writer))
|
||||||
writer->add_table_name(tab);
|
writer->add_table_name(tab);
|
||||||
}
|
}
|
||||||
void add_table_name(const TABLE* table)
|
void add_table_name(const TABLE* table)
|
||||||
{
|
{
|
||||||
if (writer)
|
if (unlikely(writer))
|
||||||
writer->add_table_name(table);
|
writer->add_table_name(table);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -333,6 +335,10 @@ public:
|
|||||||
context.init(my_writer);
|
context.init(my_writer);
|
||||||
closed= false;
|
closed= false;
|
||||||
}
|
}
|
||||||
|
bool trace_started()
|
||||||
|
{
|
||||||
|
return my_writer != 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -349,7 +355,7 @@ class Json_writer_object : public Json_writer_struct
|
|||||||
private:
|
private:
|
||||||
void add_member(const char *name)
|
void add_member(const char *name)
|
||||||
{
|
{
|
||||||
if (my_writer)
|
if (unlikely(my_writer))
|
||||||
my_writer->add_member(name);
|
my_writer->add_member(name);
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
@ -406,11 +412,11 @@ public:
|
|||||||
context.add_str(value, num_bytes);
|
context.add_str(value, num_bytes);
|
||||||
return *this;
|
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);
|
DBUG_ASSERT(!closed);
|
||||||
add_member(name);
|
add_member(name);
|
||||||
context.add_str(value.str);
|
context.add_str(value.str, value.length);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
Json_writer_object& add(const char *name, Item *value)
|
Json_writer_object& add(const char *name, Item *value)
|
||||||
@ -454,7 +460,7 @@ public:
|
|||||||
void end()
|
void end()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(!closed);
|
DBUG_ASSERT(!closed);
|
||||||
if (my_writer)
|
if (unlikely(my_writer))
|
||||||
my_writer->end_object();
|
my_writer->end_object();
|
||||||
closed= TRUE;
|
closed= TRUE;
|
||||||
}
|
}
|
||||||
@ -478,7 +484,7 @@ public:
|
|||||||
void end()
|
void end()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(!closed);
|
DBUG_ASSERT(!closed);
|
||||||
if (my_writer)
|
if (unlikely(my_writer))
|
||||||
my_writer->end_array();
|
my_writer->end_array();
|
||||||
closed= TRUE;
|
closed= TRUE;
|
||||||
}
|
}
|
||||||
@ -527,10 +533,10 @@ public:
|
|||||||
context.add_str(value, num_bytes);
|
context.add_str(value, num_bytes);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
Json_writer_array& add(LEX_CSTRING value)
|
Json_writer_array& add(const LEX_CSTRING &value)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(!closed);
|
DBUG_ASSERT(!closed);
|
||||||
context.add_str(value.str);
|
context.add_str(value.str, value.length);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
Json_writer_array& add(Item *value)
|
Json_writer_array& add(Item *value)
|
||||||
|
@ -2258,6 +2258,7 @@ public:
|
|||||||
void TRP_RANGE::trace_basic_info(PARAM *param,
|
void TRP_RANGE::trace_basic_info(PARAM *param,
|
||||||
Json_writer_object *trace_object) const
|
Json_writer_object *trace_object) const
|
||||||
{
|
{
|
||||||
|
DBUG_ASSERT(trace_object->trace_started());
|
||||||
DBUG_ASSERT(param->using_real_indexes);
|
DBUG_ASSERT(param->using_real_indexes);
|
||||||
const uint keynr_in_table= param->real_keynr[key_idx];
|
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
|
Json_writer_object *trace_object) const
|
||||||
{
|
{
|
||||||
THD *thd= param->thd;
|
THD *thd= param->thd;
|
||||||
|
DBUG_ASSERT(trace_object->trace_started());
|
||||||
trace_object->add("type", "index_roworder_union");
|
trace_object->add("type", "index_roworder_union");
|
||||||
Json_writer_array smth_trace(thd, "union_of");
|
Json_writer_array smth_trace(thd, "union_of");
|
||||||
for (TABLE_READ_PLAN **current= first_ror; current != last_ror; current++)
|
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
|
Json_writer_object *trace_object) const
|
||||||
{
|
{
|
||||||
THD *thd= param->thd;
|
THD *thd= param->thd;
|
||||||
|
DBUG_ASSERT(trace_object->trace_started());
|
||||||
trace_object->add("type", "index_sort_intersect");
|
trace_object->add("type", "index_sort_intersect");
|
||||||
Json_writer_array smth_trace(thd, "index_sort_intersect_of");
|
Json_writer_array smth_trace(thd, "index_sort_intersect_of");
|
||||||
for (TRP_RANGE **current= range_scans; current != range_scans_end;
|
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
|
Json_writer_object *trace_object) const
|
||||||
{
|
{
|
||||||
THD *thd= param->thd;
|
THD *thd= param->thd;
|
||||||
|
DBUG_ASSERT(trace_object->trace_started());
|
||||||
trace_object->add("type", "index_merge");
|
trace_object->add("type", "index_merge");
|
||||||
Json_writer_array smth_trace(thd, "index_merge_of");
|
Json_writer_array smth_trace(thd, "index_merge_of");
|
||||||
for (TRP_RANGE **current= range_scans; current != range_scans_end; current++)
|
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
|
Json_writer_object *trace_object) const
|
||||||
{
|
{
|
||||||
THD *thd= param->thd;
|
THD *thd= param->thd;
|
||||||
|
DBUG_ASSERT(trace_object->trace_started());
|
||||||
|
|
||||||
trace_object->add("type", "index_group").add("index", index_info->name);
|
trace_object->add("type", "index_group").add("index", index_info->name);
|
||||||
|
|
||||||
if (min_max_arg_part)
|
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,
|
Json_writer_array trace_range_summary(thd,
|
||||||
"setup_range_conditions");
|
"setup_range_conditions");
|
||||||
tree= cond->get_mm_tree(¶m, &cond);
|
tree= cond->get_mm_tree(¶m, &cond);
|
||||||
}
|
}
|
||||||
if (tree)
|
if (tree)
|
||||||
@ -5596,6 +5602,8 @@ ha_rows get_table_cardinality_for_index_intersect(TABLE *table)
|
|||||||
static
|
static
|
||||||
void print_keyparts(THD *thd, KEY *key, uint key_parts)
|
void print_keyparts(THD *thd, KEY *key, uint key_parts)
|
||||||
{
|
{
|
||||||
|
DBUG_ASSERT(thd->trace_started());
|
||||||
|
|
||||||
KEY_PART_INFO *part= key->key_part;
|
KEY_PART_INFO *part= key->key_part;
|
||||||
Json_writer_array keyparts= Json_writer_array(thd, "keyparts");
|
Json_writer_array keyparts= Json_writer_array(thd, "keyparts");
|
||||||
for(uint i= 0; i < key_parts; i++, part++)
|
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
|
Json_writer_object *trace_object) const
|
||||||
{
|
{
|
||||||
THD *thd= param->thd;
|
THD *thd= param->thd;
|
||||||
|
DBUG_ASSERT(trace_object->trace_started());
|
||||||
|
|
||||||
trace_object->add("type", "index_roworder_intersect");
|
trace_object->add("type", "index_roworder_intersect");
|
||||||
trace_object->add("rows", records);
|
trace_object->add("rows", records);
|
||||||
trace_object->add("cost", read_cost);
|
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);
|
trace_idx.add("chosen", false);
|
||||||
if (found_records == HA_POS_ERROR)
|
if (found_records == HA_POS_ERROR)
|
||||||
|
{
|
||||||
if (key->type == SEL_ARG::Type::MAYBE_KEY)
|
if (key->type == SEL_ARG::Type::MAYBE_KEY)
|
||||||
trace_idx.add("cause", "depends on unread values");
|
trace_idx.add("cause", "depends on unread values");
|
||||||
else
|
else
|
||||||
trace_idx.add("cause", "unknown");
|
trace_idx.add("cause", "unknown");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
trace_idx.add("cause", "cost");
|
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};
|
sel_arg_range_seq_next, 0, 0};
|
||||||
KEY *keyinfo= param->table->key_info + param->real_keynr[idx];
|
KEY *keyinfo= param->table->key_info + param->real_keynr[idx];
|
||||||
uint n_key_parts= param->table->actual_n_key_parts(keyinfo);
|
uint n_key_parts= param->table->actual_n_key_parts(keyinfo);
|
||||||
|
DBUG_ASSERT(range_trace->trace_started());
|
||||||
seq.keyno= idx;
|
seq.keyno= idx;
|
||||||
seq.real_keyno= param->real_keynr[idx];
|
seq.real_keyno= param->real_keynr[idx];
|
||||||
seq.param= param;
|
seq.param= param;
|
||||||
|
@ -3050,12 +3050,13 @@ bool Sj_materialization_picker::check_qep(JOIN *join,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Json_writer_object trace(join->thd);
|
|
||||||
trace.add("strategy", "SJ-Materialization");
|
|
||||||
/* This is SJ-Materialization with lookups */
|
/* This is SJ-Materialization with lookups */
|
||||||
Cost_estimate prefix_cost;
|
Cost_estimate prefix_cost;
|
||||||
signed int first_tab= (int)idx - mat_info->tables;
|
signed int first_tab= (int)idx - mat_info->tables;
|
||||||
double prefix_rec_count;
|
double prefix_rec_count;
|
||||||
|
Json_writer_object trace(join->thd);
|
||||||
|
trace.add("strategy", "SJ-Materialization");
|
||||||
|
|
||||||
if (first_tab < (int)join->const_tables)
|
if (first_tab < (int)join->const_tables)
|
||||||
{
|
{
|
||||||
prefix_cost.reset();
|
prefix_cost.reset();
|
||||||
@ -3084,7 +3085,7 @@ bool Sj_materialization_picker::check_qep(JOIN *join,
|
|||||||
*record_count= prefix_rec_count;
|
*record_count= prefix_rec_count;
|
||||||
*handled_fanout= new_join_tab->emb_sj_nest->sj_inner_tables;
|
*handled_fanout= new_join_tab->emb_sj_nest->sj_inner_tables;
|
||||||
*strategy= SJ_OPT_MATERIALIZE;
|
*strategy= SJ_OPT_MATERIALIZE;
|
||||||
if (unlikely(join->thd->trace_started()))
|
if (unlikely(trace.trace_started()))
|
||||||
{
|
{
|
||||||
trace.add("records", *record_count);
|
trace.add("records", *record_count);
|
||||||
trace.add("read_time", *read_time);
|
trace.add("read_time", *read_time);
|
||||||
@ -3166,7 +3167,7 @@ bool Sj_materialization_picker::check_qep(JOIN *join,
|
|||||||
*/
|
*/
|
||||||
*record_count= prefix_rec_count;
|
*record_count= prefix_rec_count;
|
||||||
*handled_fanout= mat_nest->sj_inner_tables;
|
*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("records", *record_count);
|
||||||
trace.add("read_time", *read_time);
|
trace.add("read_time", *read_time);
|
||||||
@ -3266,7 +3267,7 @@ bool LooseScan_picker::check_qep(JOIN *join,
|
|||||||
*/
|
*/
|
||||||
*strategy= SJ_OPT_LOOSE_SCAN;
|
*strategy= SJ_OPT_LOOSE_SCAN;
|
||||||
*handled_fanout= first->table->emb_sj_nest->sj_inner_tables;
|
*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("records", *record_count);
|
||||||
trace.add("read_time", *read_time);
|
trace.add("read_time", *read_time);
|
||||||
@ -3384,7 +3385,7 @@ bool Firstmatch_picker::check_qep(JOIN *join,
|
|||||||
*handled_fanout= firstmatch_need_tables;
|
*handled_fanout= firstmatch_need_tables;
|
||||||
/* *record_count and *read_time were set by the above call */
|
/* *record_count and *read_time were set by the above call */
|
||||||
*strategy= SJ_OPT_FIRST_MATCH;
|
*strategy= SJ_OPT_FIRST_MATCH;
|
||||||
if (unlikely(join->thd->trace_started()))
|
if (unlikely(trace.trace_started()))
|
||||||
{
|
{
|
||||||
trace.add("records", *record_count);
|
trace.add("records", *record_count);
|
||||||
trace.add("read_time", *read_time);
|
trace.add("read_time", *read_time);
|
||||||
@ -3469,6 +3470,7 @@ bool Duplicate_weedout_picker::check_qep(JOIN *join,
|
|||||||
uint temptable_rec_size;
|
uint temptable_rec_size;
|
||||||
Json_writer_object trace(join->thd);
|
Json_writer_object trace(join->thd);
|
||||||
trace.add("strategy", "DuplicateWeedout");
|
trace.add("strategy", "DuplicateWeedout");
|
||||||
|
|
||||||
if (first_tab == join->const_tables)
|
if (first_tab == join->const_tables)
|
||||||
{
|
{
|
||||||
prefix_rec_count= 1.0;
|
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;
|
*record_count= prefix_rec_count * sj_outer_fanout;
|
||||||
*handled_fanout= dups_removed_fanout;
|
*handled_fanout= dups_removed_fanout;
|
||||||
*strategy= SJ_OPT_DUPS_WEEDOUT;
|
*strategy= SJ_OPT_DUPS_WEEDOUT;
|
||||||
if (unlikely(join->thd->trace_started()))
|
if (unlikely(trace.trace_started()))
|
||||||
{
|
{
|
||||||
trace.add("records", *record_count);
|
trace.add("records", *record_count);
|
||||||
trace.add("read_time", *read_time);
|
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)
|
void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
|
||||||
{
|
{
|
||||||
|
join->sjm_lookup_tables= 0;
|
||||||
|
join->sjm_scan_tables= 0;
|
||||||
|
if (!join->select_lex->sj_nests.elements)
|
||||||
|
return;
|
||||||
|
|
||||||
|
THD *thd= join->thd;
|
||||||
uint table_count=join->table_count;
|
uint table_count=join->table_count;
|
||||||
uint tablenr;
|
uint tablenr;
|
||||||
table_map remaining_tables= 0;
|
table_map remaining_tables= 0;
|
||||||
table_map handled_tabs= 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;
|
|
||||||
Json_writer_object trace_wrapper(thd);
|
Json_writer_object trace_wrapper(thd);
|
||||||
Json_writer_array trace_semijoin_strategies(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--)
|
for (tablenr= table_count - 1 ; tablenr != join->const_tables - 1; tablenr--)
|
||||||
{
|
{
|
||||||
POSITION *pos= join->best_positions + tablenr;
|
POSITION *pos= join->best_positions + tablenr;
|
||||||
|
@ -105,8 +105,8 @@ void opt_trace_print_expanded_query(THD *thd, SELECT_LEX *select_lex,
|
|||||||
Json_writer_object *writer)
|
Json_writer_object *writer)
|
||||||
|
|
||||||
{
|
{
|
||||||
if (!thd->trace_started())
|
DBUG_ASSERT(thd->trace_started());
|
||||||
return;
|
|
||||||
StringBuffer<1024> str(system_charset_info);
|
StringBuffer<1024> str(system_charset_info);
|
||||||
ulonglong save_option_bits= thd->variables.option_bits;
|
ulonglong save_option_bits= thd->variables.option_bits;
|
||||||
thd->variables.option_bits &= ~OPTION_QUOTE_SHOW_CREATE;
|
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 &
|
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())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Opt_trace_context *const trace= &thd->opt_trace;
|
Opt_trace_context *const trace= &thd->opt_trace;
|
||||||
if (!thd->trace_started())
|
|
||||||
return;
|
|
||||||
bool full_access;
|
bool full_access;
|
||||||
Security_context *const backup_thd_sctx= thd->security_context();
|
Security_context *const backup_thd_sctx= thd->security_context();
|
||||||
thd->set_security_context(&thd->main_security_ctx);
|
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)
|
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)) || thd->system_thread)
|
Opt_trace_context::FLAG_ENABLED)) ||
|
||||||
|
thd->system_thread ||
|
||||||
|
!thd->trace_started())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Opt_trace_context *const trace= &thd->opt_trace;
|
Opt_trace_context *const trace= &thd->opt_trace;
|
||||||
|
|
||||||
if (!thd->trace_started())
|
|
||||||
return;
|
|
||||||
|
|
||||||
Security_context *const backup_thd_sctx= thd->security_context();
|
Security_context *const backup_thd_sctx= thd->security_context();
|
||||||
thd->set_security_context(&thd->main_security_ctx);
|
thd->set_security_context(&thd->main_security_ctx);
|
||||||
const TABLE_LIST *const first_not_own_table= thd->lex->first_not_own_table();
|
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 &
|
if (likely(!(thd->variables.optimizer_trace &
|
||||||
Opt_trace_context::FLAG_ENABLED)) ||
|
Opt_trace_context::FLAG_ENABLED)) ||
|
||||||
thd->system_thread)
|
thd->system_thread ||
|
||||||
return;
|
!thd->trace_started())
|
||||||
Opt_trace_context *const trace= &thd->opt_trace;
|
|
||||||
if (!thd->trace_started())
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Opt_trace_context *const trace= &thd->opt_trace;
|
||||||
Security_context *const backup_table_sctx= view->security_ctx;
|
Security_context *const backup_table_sctx= view->security_ctx;
|
||||||
Security_context *const backup_thd_sctx= thd->security_context();
|
Security_context *const backup_thd_sctx= thd->security_context();
|
||||||
const GRANT_INFO backup_grant_info= view->grant;
|
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)
|
void Json_writer::add_table_name(const JOIN_TAB *tab)
|
||||||
{
|
{
|
||||||
|
DBUG_ASSERT(tab->join->thd->trace_started());
|
||||||
if (tab != NULL)
|
if (tab != NULL)
|
||||||
{
|
{
|
||||||
char table_name_buffer[SAFE_NAME_LEN];
|
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)
|
void add_table_scan_values_to_trace(THD *thd, JOIN_TAB *tab)
|
||||||
{
|
{
|
||||||
|
DBUG_ASSERT(thd->trace_started());
|
||||||
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");
|
||||||
@ -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)
|
void trace_plan_prefix(JOIN *join, uint idx, table_map join_tables)
|
||||||
{
|
{
|
||||||
THD *const thd= join->thd;
|
THD *const thd= join->thd;
|
||||||
|
DBUG_ASSERT(thd->trace_started());
|
||||||
|
|
||||||
Json_writer_array plan_prefix(thd, "plan_prefix");
|
Json_writer_array plan_prefix(thd, "plan_prefix");
|
||||||
for (uint i= 0; i < idx; i++)
|
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)
|
void print_final_join_order(JOIN *join)
|
||||||
{
|
{
|
||||||
|
DBUG_ASSERT(join->thd->trace_started());
|
||||||
|
|
||||||
Json_writer_object join_order(join->thd);
|
Json_writer_object join_order(join->thd);
|
||||||
Json_writer_array best_order(join->thd, "best_join_order");
|
Json_writer_array best_order(join->thd, "best_join_order");
|
||||||
JOIN_TAB *j;
|
JOIN_TAB *j;
|
||||||
@ -692,6 +695,8 @@ void print_final_join_order(JOIN *join)
|
|||||||
void print_best_access_for_table(THD *thd, POSITION *pos,
|
void print_best_access_for_table(THD *thd, POSITION *pos,
|
||||||
enum join_type type)
|
enum join_type type)
|
||||||
{
|
{
|
||||||
|
DBUG_ASSERT(thd->trace_started());
|
||||||
|
|
||||||
Json_writer_object trace_best_access(thd, "chosen_access_method");
|
Json_writer_object trace_best_access(thd, "chosen_access_method");
|
||||||
trace_best_access.add("type", type == JT_ALL ? "scan" :
|
trace_best_access.add("type", type == JT_ALL ? "scan" :
|
||||||
join_type_str[type]);
|
join_type_str[type]);
|
||||||
|
@ -2205,11 +2205,6 @@ void THD::reset_globals()
|
|||||||
net.thd= 0;
|
net.thd= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool THD::trace_started()
|
|
||||||
{
|
|
||||||
return opt_trace.is_started();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Cleanup after query.
|
Cleanup after query.
|
||||||
|
|
||||||
|
@ -3274,7 +3274,10 @@ public:
|
|||||||
void reset_for_reuse();
|
void reset_for_reuse();
|
||||||
bool store_globals();
|
bool store_globals();
|
||||||
void reset_globals();
|
void reset_globals();
|
||||||
bool trace_started();
|
bool trace_started()
|
||||||
|
{
|
||||||
|
return opt_trace.is_started();
|
||||||
|
}
|
||||||
#ifdef SIGNAL_WITH_VIO_CLOSE
|
#ifdef SIGNAL_WITH_VIO_CLOSE
|
||||||
inline void set_active_vio(Vio* vio)
|
inline void set_active_vio(Vio* vio)
|
||||||
{
|
{
|
||||||
@ -5003,6 +5006,7 @@ public:
|
|||||||
Item *sp_fix_func_item(Item **it_addr);
|
Item *sp_fix_func_item(Item **it_addr);
|
||||||
Item *sp_prepare_func_item(Item **it_addr, uint cols= 1);
|
Item *sp_prepare_func_item(Item **it_addr, uint cols= 1);
|
||||||
bool sp_eval_expr(Field *result_field, Item **expr_item_ptr);
|
bool sp_eval_expr(Field *result_field, Item **expr_item_ptr);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A short cut for thd->get_stmt_da()->set_ok_status(). */
|
/** A short cut for thd->get_stmt_da()->set_ok_status(). */
|
||||||
|
@ -353,8 +353,10 @@ bool dbug_user_var_equals_int(THD *thd, const char *name, int value)
|
|||||||
static void trace_table_dependencies(THD *thd,
|
static void trace_table_dependencies(THD *thd,
|
||||||
JOIN_TAB *join_tabs, uint table_count)
|
JOIN_TAB *join_tabs, uint table_count)
|
||||||
{
|
{
|
||||||
|
DBUG_ASSERT(thd->trace_started());
|
||||||
Json_writer_object trace_wrapper(thd);
|
Json_writer_object trace_wrapper(thd);
|
||||||
Json_writer_array trace_dep(thd, "table_dependencies");
|
Json_writer_array trace_dep(thd, "table_dependencies");
|
||||||
|
|
||||||
for (uint i= 0; i < table_count; i++)
|
for (uint i= 0; i < table_count; i++)
|
||||||
{
|
{
|
||||||
TABLE_LIST *table_ref= join_tabs[i].tab_list;
|
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);
|
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);
|
||||||
@ -5352,6 +5355,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
|
|||||||
{
|
{
|
||||||
Json_writer_object rows_estimation_wrapper(thd);
|
Json_writer_object rows_estimation_wrapper(thd);
|
||||||
Json_writer_array rows_estimation(thd, "rows_estimation");
|
Json_writer_array rows_estimation(thd, "rows_estimation");
|
||||||
|
|
||||||
for (s=stat ; s < stat_end ; s++)
|
for (s=stat ; s < stat_end ; s++)
|
||||||
{
|
{
|
||||||
s->startup_cost= 0;
|
s->startup_cost= 0;
|
||||||
@ -5496,10 +5500,16 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
|
|||||||
if (select)
|
if (select)
|
||||||
delete select;
|
delete select;
|
||||||
else
|
else
|
||||||
add_table_scan_values_to_trace(thd, s);
|
{
|
||||||
|
if (thd->trace_started())
|
||||||
|
add_table_scan_values_to_trace(thd, s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
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);
|
Json_writer_object trace_access_idx(thd);
|
||||||
/*
|
/*
|
||||||
ft-keys require special treatment
|
full text keys require special treatment
|
||||||
*/
|
*/
|
||||||
if (ft_key)
|
if (ft_key)
|
||||||
{
|
{
|
||||||
@ -7414,7 +7424,7 @@ 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])
|
trace_access_idx.add("access_type", join_type_str[type])
|
||||||
.add("index", keyinfo->name);
|
.add("full-text index", keyinfo->name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -11866,18 +11876,21 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_attached_comp.end();
|
if (unlikely(thd->trace_started()))
|
||||||
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)
|
trace_attached_comp.end();
|
||||||
continue;
|
Json_writer_array trace_attached_summary(thd,
|
||||||
Item *const cond = tab->select_cond;
|
"attached_conditions_summary");
|
||||||
Json_writer_object trace_one_table(thd);
|
for (tab= first_depth_first_tab(join); tab;
|
||||||
trace_one_table.add_table_name(tab);
|
tab= next_depth_first_tab(join, tab))
|
||||||
trace_one_table.add("attached", cond);
|
{
|
||||||
|
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);
|
DBUG_RETURN(0);
|
||||||
|
@ -658,9 +658,12 @@ Memory allocated by threads: %s\n",
|
|||||||
|
|
||||||
void print_keyuse_array_for_trace(THD *thd, DYNAMIC_ARRAY *keyuse_array)
|
void print_keyuse_array_for_trace(THD *thd, DYNAMIC_ARRAY *keyuse_array)
|
||||||
{
|
{
|
||||||
|
DBUG_ASSERT(thd->trace_started());
|
||||||
|
|
||||||
Json_writer_object wrapper(thd);
|
Json_writer_object wrapper(thd);
|
||||||
Json_writer_array trace_key_uses(thd, "ref_optimizer_key_uses");
|
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);
|
KEYUSE *keyuse= (KEYUSE*)dynamic_array_ptr(keyuse_array, i);
|
||||||
Json_writer_object keyuse_elem(thd);
|
Json_writer_object keyuse_elem(thd);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user