summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Petrunya <psergey@askmonty.org>2013-10-09 09:40:33 +0400
committerSergey Petrunya <psergey@askmonty.org>2013-10-09 09:40:33 +0400
commit161d68759433b0315a6b95209d3db86be411a686 (patch)
tree8d7123f8b473ae696bf3bf89bf5191afcad986f8
parent69e6a2bb22434d94d96312ba8a0540195273dfdd (diff)
downloadmariadb-git-161d68759433b0315a6b95209d3db86be411a686.tar.gz
MDEV-3798: EXPLAIN UPDATE/DELETE
- Generate correct contents of `Extra` column for UPDATEs/DELETEs that use quick selects - UPDATEs with used_key_is_modified=true will show "Using buffer"
-rw-r--r--sql/sql_delete.cc8
-rw-r--r--sql/sql_explain.cc42
-rw-r--r--sql/sql_explain.h3
-rw-r--r--sql/sql_lex.h16
-rw-r--r--sql/sql_update.cc24
5 files changed, 73 insertions, 20 deletions
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 19401496a74..15dfe3e6c7c 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -142,14 +142,16 @@ void Update_plan::save_explain_data_intern(Explain_query *query,
explain->using_where= test(select && select->cond);
explain->using_filesort= using_filesort;
+ explain->using_io_buffer= using_io_buffer;
make_possible_keys_line(table, possible_keys, &explain->possible_keys_line);
+ explain->quick_info= NULL;
+
/* Calculate key_len */
if (select && select->quick)
{
- select->quick->add_keys_and_lengths(&explain->key_str,
- &explain->key_len_str);
+ explain->quick_info= select->quick->get_explain(mem_root);
}
else
{
@@ -218,7 +220,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
killed_state killed_status= NOT_KILLED;
THD::enum_binlog_query_type query_type= THD::ROW_QUERY_TYPE;
bool with_select= !select_lex->item_list.is_empty();
- Delete_plan query_plan;
+ Delete_plan query_plan(thd->mem_root);
query_plan.index= MAX_KEY;
query_plan.using_filesort= FALSE;
DBUG_ENTER("mysql_delete");
diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc
index a8afc0ac6d3..91a73cfb7d3 100644
--- a/sql/sql_explain.cc
+++ b/sql/sql_explain.cc
@@ -793,6 +793,8 @@ int Explain_update::print_explain(Explain_query *query,
select_result_sink *output,
uint8 explain_flags)
{
+ StringBuffer<64> key_buf;
+ StringBuffer<64> key_len_buf;
StringBuffer<64> extra_str;
if (impossible_where || no_partitions)
{
@@ -807,8 +809,32 @@ int Explain_update::print_explain(Explain_query *query,
return res;
}
+
+ if (quick_info)
+ {
+ quick_info->print_key(&key_buf);
+ quick_info->print_key_len(&key_len_buf);
+
+ StringBuffer<64> quick_buf;
+ quick_info->print_extra(&quick_buf);
+ if (quick_buf.length())
+ {
+ extra_str.append(STRING_WITH_LEN("Using "));
+ extra_str.append(quick_buf);
+ }
+ }
+ else
+ {
+ key_buf.copy(key_str);
+ key_len_buf.copy(key_len_str);
+ }
+
if (using_where)
+ {
+ if (extra_str.length() !=0)
+ extra_str.append(STRING_WITH_LEN("; "));
extra_str.append(STRING_WITH_LEN("Using where"));
+ }
if (mrr_type.length() != 0)
{
@@ -816,7 +842,7 @@ int Explain_update::print_explain(Explain_query *query,
extra_str.append(STRING_WITH_LEN("; "));
extra_str.append(mrr_type);
}
-
+
if (using_filesort)
{
if (extra_str.length() !=0)
@@ -824,6 +850,13 @@ int Explain_update::print_explain(Explain_query *query,
extra_str.append(STRING_WITH_LEN("Using filesort"));
}
+ if (using_io_buffer)
+ {
+ if (extra_str.length() !=0)
+ extra_str.append(STRING_WITH_LEN("; "));
+ extra_str.append(STRING_WITH_LEN("Using buffer"));
+ }
+
/*
Single-table DELETE commands do not do "Using temporary".
"Using index condition" is also not possible (which is an unjustified limitation)
@@ -836,8 +869,8 @@ int Explain_update::print_explain(Explain_query *query,
used_partitions_set? used_partitions.c_ptr() : NULL,
jtype,
possible_keys_line.length()? possible_keys_line.c_ptr(): NULL,
- key_str.length()? key_str.c_ptr() : NULL,
- key_len_str.length() ? key_len_str.c_ptr() : NULL,
+ key_buf.length()? key_buf.c_ptr() : NULL,
+ key_len_buf.length() ? key_len_buf.c_ptr() : NULL,
NULL, /* 'ref' is always NULL in single-table EXPLAIN DELETE */
&rows,
extra_str.c_ptr());
@@ -846,7 +879,8 @@ int Explain_update::print_explain(Explain_query *query,
}
-int Explain_insert::print_explain(Explain_query *query, select_result_sink *output,
+int Explain_insert::print_explain(Explain_query *query,
+ select_result_sink *output,
uint8 explain_flags)
{
const char *select_type="INSERT";
diff --git a/sql/sql_explain.h b/sql/sql_explain.h
index 07493cfa14d..2eb9e528a67 100644
--- a/sql/sql_explain.h
+++ b/sql/sql_explain.h
@@ -486,10 +486,13 @@ public:
StringBuffer<128> key_len_str;
StringBuffer<64> mrr_type;
+ Explain_quick_select *quick_info;
+
bool using_where;
ha_rows rows;
bool using_filesort;
+ bool using_io_buffer;
virtual int print_explain(Explain_query *query, select_result_sink *output,
uint8 explain_flags);
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 21f3b5a5859..9515079e75f 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -2390,6 +2390,9 @@ public:
select should not be shown when printing EXPLAIN.
*/
bool updating_a_view;
+
+ /* Allocate things there */
+ MEM_ROOT *mem_root;
TABLE *table;
SQL_SELECT *select;
@@ -2403,6 +2406,7 @@ public:
key_map possible_keys;
bool using_filesort;
+ bool using_io_buffer;
/* Set this plan to be a plan to do nothing because of impossible WHERE */
void set_impossible_where() { impossible_where= true; }
@@ -2412,8 +2416,10 @@ public:
void save_explain_data_intern(Explain_query *query, Explain_update *eu);
virtual ~Update_plan() {}
- Update_plan() :
- impossible_where(false), no_partitions(false), using_filesort(false)
+ Update_plan(MEM_ROOT *mem_root_arg) :
+ impossible_where(false), no_partitions(false),
+ mem_root(mem_root_arg),
+ using_filesort(false), using_io_buffer(false)
{}
};
@@ -2425,8 +2431,10 @@ class Delete_plan : public Update_plan
public:
/* Construction functions */
- Delete_plan() :
- deleting_all_rows(false) {}
+ Delete_plan(MEM_ROOT *mem_root_arg) :
+ Update_plan(mem_root_arg),
+ deleting_all_rows(false)
+ {}
/* Set this query plan to be a plan to make a call to h->delete_all_rows() */
void set_delete_all_rows(ha_rows rows_arg)
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 6842f58d92e..5b2333657e1 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -276,7 +276,7 @@ int mysql_update(THD *thd,
ulonglong id;
List<Item> all_fields;
killed_state killed_status= NOT_KILLED;
- Update_plan query_plan;
+ Update_plan query_plan(thd->mem_root);
query_plan.index= MAX_KEY;
query_plan.using_filesort= FALSE;
bool apc_target_enabled= false; // means was enabled *by code this function*
@@ -495,6 +495,17 @@ int mysql_update(THD *thd,
query_plan.table_rows= table->file->stats.records;
query_plan.possible_keys= select? select->possible_keys: key_map(0);
+ if (used_key_is_modified || order ||
+ partition_key_modified(table, table->write_set))
+ {
+ if (order && (need_sort || used_key_is_modified))
+ query_plan.using_filesort= true;
+ else
+ query_plan.using_io_buffer= true;
+ }
+
+ query_plan.save_explain_data(thd->lex->explain);
+
/*
Ok, we have generated a query plan for the UPDATE.
- if we're running EXPLAIN UPDATE, goto produce explain output
@@ -502,16 +513,12 @@ int mysql_update(THD *thd,
*/
if (thd->lex->describe)
goto exit_without_my_ok;
-
- query_plan.save_explain_data(thd->lex->explain);
thd->apc_target.enable();
apc_target_enabled= true;
DBUG_EXECUTE_IF("show_explain_probe_update_exec_start",
dbug_serve_apcs(thd, 1););
-
-
- if (used_key_is_modified || order ||
- partition_key_modified(table, table->write_set))
+
+ if (query_plan.using_filesort || query_plan.using_io_buffer)
{
/*
We can't update table directly; We must first search after all
@@ -528,7 +535,7 @@ int mysql_update(THD *thd,
table->use_all_columns();
/* note: We avoid sorting if we sort on the used index */
- if (order && (need_sort || used_key_is_modified))
+ if (query_plan.using_filesort)
{
/*
Doing an ORDER BY; Let filesort find and sort the rows we are going
@@ -1034,7 +1041,6 @@ err:
exit_without_my_ok:
DBUG_ASSERT(!apc_target_enabled);
- query_plan.save_explain_data(thd->lex->explain);
int err2= thd->lex->explain->send_explain(thd);