diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2013-10-08 16:13:49 +0400 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2013-10-08 16:13:49 +0400 |
commit | 69e6a2bb22434d94d96312ba8a0540195273dfdd (patch) | |
tree | c84e3440a7d6f55c9e8c7c53415eba21c326fbcb | |
parent | fda46df62071f54ebc4d806c6d9caf031d801150 (diff) | |
download | mariadb-git-69e6a2bb22434d94d96312ba8a0540195273dfdd.tar.gz |
MDEV-3798: EXPLAIN UPDATE/DELETE
- Update test results after last few csets
- Generate correct value for `possible_keys` column for single table UPDATE/DELETE.
-rw-r--r-- | mysql-test/r/explain_non_select.result | 6 | ||||
-rw-r--r-- | sql/opt_range.cc | 14 | ||||
-rw-r--r-- | sql/opt_range.h | 2 | ||||
-rw-r--r-- | sql/sql_delete.cc | 2 | ||||
-rw-r--r-- | sql/sql_update.cc | 2 |
5 files changed, 21 insertions, 5 deletions
diff --git a/mysql-test/r/explain_non_select.result b/mysql-test/r/explain_non_select.result index 1c5d545fd99..d118cd7b4e7 100644 --- a/mysql-test/r/explain_non_select.result +++ b/mysql-test/r/explain_non_select.result @@ -13,7 +13,7 @@ id select_type table type possible_keys key key_len ref rows Extra # DELETE without WHERE is a special case: explain delete from t0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Deleting all rows +1 SIMPLE NULL NULL NULL NULL NULL NULL 8 Deleting all rows create table t1 (a int, b int, filler char(100), key(a), key(b)); insert into t1 select A.a+10*B.a + 10*C.a, A.a+10*B.a + 10*C.a, 'filler' @@ -65,10 +65,10 @@ select A.a+10*B.a + 10*C.a, A.a+10*B.a + 10*C.a, 'filler' from t0 A, t0 B, t0 C; explain update t1 set a=a+1 where 3>4; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible where +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE explain update t1 set a=a+1 where a=3 and a=4; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible where +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE # This should use an index, possible_keys=NULL because there is no WHERE explain update t1 set a=a+1 order by a limit 2; id select_type table type possible_keys key key_len ref rows Extra diff --git a/sql/opt_range.cc b/sql/opt_range.cc index eec15ed93f9..08d9df2a10a 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -861,6 +861,14 @@ class PARAM : public RANGE_OPT_PARAM { public: ha_rows quick_rows[MAX_KEY]; + + /* + This will collect 'possible keys' based on the range optimization. + + Queries with a JOIN object actually use ref optimizer (see add_key_field) + to collect possible_keys. This is used by single table UPDATE/DELETE. + */ + key_map possible_keys; longlong baseflag; uint max_key_part, range_count; @@ -2955,6 +2963,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, read_time= (double) records + scan_time + 1; // Force to use index else if (read_time <= 2.0 && !force_quick_range) DBUG_RETURN(0); /* No need for quick select */ + + possible_keys.clear_all(); DBUG_PRINT("info",("Time to scan table: %g", read_time)); @@ -2986,6 +2996,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, param.using_real_indexes= TRUE; param.remove_jump_scans= TRUE; param.force_default_mrr= ordered_output; + param.possible_keys.clear_all(); thd->no_errors=1; // Don't warn about NULL init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0, @@ -3197,6 +3208,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, quick= NULL; } } + possible_keys= param.possible_keys; free_mem: free_root(&alloc,MYF(0)); // Return memory & allocator @@ -3204,6 +3216,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, thd->no_errors=0; } + DBUG_EXECUTE("info", print_quick(quick, &needed_reg);); /* @@ -10467,6 +10480,7 @@ ha_rows check_quick_select(PARAM *param, uint idx, bool index_only, if (rows != HA_POS_ERROR) { param->quick_rows[keynr]= rows; + param->possible_keys.set_bit(keynr); if (update_tbl_stats) { param->table->quick_keys.set_bit(keynr); diff --git a/sql/opt_range.h b/sql/opt_range.h index 29bb9ed88ff..d61219b7dd0 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -982,6 +982,8 @@ class SQL_SELECT :public Sql_alloc { key_map quick_keys; // Possible quick keys key_map needed_reg; // Possible quick keys after prev tables. table_map const_tables,read_tables; + /* See PARAM::possible_keys */ + key_map possible_keys; bool free_cond; /* Currently not used and always FALSE */ SQL_SELECT(); diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 50a5ec79166..19401496a74 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -436,7 +436,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, } query_plan.select= select; - query_plan.possible_keys= table->quick_keys; + query_plan.possible_keys= select? select->possible_keys: key_map(0); query_plan.table_rows= table->file->stats.records; /* diff --git a/sql/sql_update.cc b/sql/sql_update.cc index bc2c5c69adb..6842f58d92e 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -492,8 +492,8 @@ int mysql_update(THD *thd, - if we're running EXPLAIN UPDATE, get out */ query_plan.select= select; - query_plan.possible_keys= table->quick_keys; query_plan.table_rows= table->file->stats.records; + query_plan.possible_keys= select? select->possible_keys: key_map(0); /* Ok, we have generated a query plan for the UPDATE. |