Commit 3bf08e54 authored by Igor Babaev's avatar Igor Babaev

Added two new flags for the optimizer switch:

'derived_merge':
  - if the flag is off then all derived tables are materialized
  - if the flag is on then mergeable derived tables are merged
'derived_with_keys':
  - if the flag is off then no keys are created for derived tables
  - if the flag is on then for any derived table a key to access 
    the derived table may be created.

Now by default both flags are on.
Later the default values for the flags will be off to comply with
the current behaviour of mysql-5.1. 

Uncommented previously commented out test case from parts.partition_repair_myisam
after having added an explicit requirement to materialize the derived
table used in the test case.  

 
parent f03a3ee5
This diff is collapsed.
...@@ -393,6 +393,20 @@ partition b a length(c) ...@@ -393,6 +393,20 @@ partition b a length(c)
6 34 6 row 2 64 6 34 6 row 2 64
6 83 64 6 83 64
6 97 zzzzzZzzzzz 64 6 97 zzzzzZzzzzz 64
SET @save_optimizer_switch= @@optimizer_switch;
SET @@optimizer_switch='derived_merge=off';
SELECT (b % 7) AS partition, b, a FROM (SELECT b,a FROM t1_will_crash) q
WHERE (b % 7) = 6
ORDER BY partition, b, a;
partition b a
6 6 jkl
6 13 ooo
6 34 6 row 2
6 48 6 row 4
6 62 6 row 6
6 83
6 97 zzzzzZzzzzz
SET @@optimizer_switch=@save_optimizer_switch;
ALTER TABLE t1_will_crash CHECK PARTITION p6; ALTER TABLE t1_will_crash CHECK PARTITION p6;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1_will_crash check warning Size of datafile is: 868 Should be: 604 test.t1_will_crash check warning Size of datafile is: 868 Should be: 604
......
...@@ -230,10 +230,12 @@ FLUSH TABLES; ...@@ -230,10 +230,12 @@ FLUSH TABLES;
SELECT (b % 7) AS partition, b, a, length(c) FROM t1_will_crash SELECT (b % 7) AS partition, b, a, length(c) FROM t1_will_crash
WHERE (b % 7) = 6 WHERE (b % 7) = 6
ORDER BY partition, b, a; ORDER BY partition, b, a;
# !!! The next test case has to be changed to provide the same result set as before mwl106 SET @save_optimizer_switch= @@optimizer_switch;
# SELECT (b % 7) AS partition, b, a FROM (SELECT b,a FROM t1_will_crash) q SET @@optimizer_switch='derived_merge=off';
# WHERE (b % 7) = 6 SELECT (b % 7) AS partition, b, a FROM (SELECT b,a FROM t1_will_crash) q
# ORDER BY partition, b, a; WHERE (b % 7) = 6
ORDER BY partition, b, a;
SET @@optimizer_switch=@save_optimizer_switch;
# NOTE: REBUILD PARTITION without CHECK before, 2 + (1) records will be lost! # NOTE: REBUILD PARTITION without CHECK before, 2 + (1) records will be lost!
#ALTER TABLE t1_will_crash REBUILD PARTITION p6; #ALTER TABLE t1_will_crash REBUILD PARTITION p6;
ALTER TABLE t1_will_crash CHECK PARTITION p6; ALTER TABLE t1_will_crash CHECK PARTITION p6;
......
...@@ -568,36 +568,37 @@ protected: ...@@ -568,36 +568,37 @@ protected:
#define OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT 8 #define OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT 8
#define OPTIMIZER_SWITCH_INDEX_MERGE_SORT_INTERSECT 16 #define OPTIMIZER_SWITCH_INDEX_MERGE_SORT_INTERSECT 16
#define OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN 32 #define OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN 32
#define OPTIMIZER_SWITCH_DERIVED_MERGE 64
#define OPTIMIZER_SWITCH_FIRSTMATCH 64 #define OPTIMIZER_SWITCH_DERIVED_WITH_KEYS 128
#define OPTIMIZER_SWITCH_LOOSE_SCAN 128 #define OPTIMIZER_SWITCH_FIRSTMATCH 256
#define OPTIMIZER_SWITCH_MATERIALIZATION 256 #define OPTIMIZER_SWITCH_LOOSE_SCAN 512
#define OPTIMIZER_SWITCH_IN_TO_EXISTS 512 #define OPTIMIZER_SWITCH_MATERIALIZATION 1024
#define OPTIMIZER_SWITCH_SEMIJOIN 1024 #define OPTIMIZER_SWITCH_IN_TO_EXISTS (1<<11)
#define OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE (1<<11) #define OPTIMIZER_SWITCH_SEMIJOIN (1<<12)
#define OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN (1<<12) #define OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE (1<<13)
#define OPTIMIZER_SWITCH_SUBQUERY_CACHE (1<<13) #define OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN (1<<14)
#define OPTIMIZER_SWITCH_SUBQUERY_CACHE (1<<15)
/** If this is off, MRR is never used. */ /** If this is off, MRR is never used. */
#define OPTIMIZER_SWITCH_MRR (1ULL << 14) #define OPTIMIZER_SWITCH_MRR (1ULL << 16)
/** /**
If OPTIMIZER_SWITCH_MRR is on and this is on, MRR is used depending on a If OPTIMIZER_SWITCH_MRR is on and this is on, MRR is used depending on a
cost-based choice ("automatic"). If OPTIMIZER_SWITCH_MRR is on and this is cost-based choice ("automatic"). If OPTIMIZER_SWITCH_MRR is on and this is
off, MRR is "forced" (i.e. used as long as the storage engine is capable of off, MRR is "forced" (i.e. used as long as the storage engine is capable of
doing it). doing it).
*/ */
#define OPTIMIZER_SWITCH_MRR_COST_BASED (1ULL << 15) #define OPTIMIZER_SWITCH_MRR_COST_BASED (1ULL << 17)
#define OPTIMIZER_SWITCH_MRR_SORT_KEYS (1ULL << 16) #define OPTIMIZER_SWITCH_MRR_SORT_KEYS (1ULL << 18)
#define OPTIMIZER_SWITCH_OUTER_JOIN_WITH_CACHE (1ULL << 17) #define OPTIMIZER_SWITCH_OUTER_JOIN_WITH_CACHE (1ULL << 19)
#define OPTIMIZER_SWITCH_SEMIJOIN_WITH_CACHE (1ULL << 18) #define OPTIMIZER_SWITCH_SEMIJOIN_WITH_CACHE (1ULL << 20)
#define OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL (1ULL << 19) #define OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL (1ULL << 21)
#define OPTIMIZER_SWITCH_JOIN_CACHE_HASHED (1ULL << 20) #define OPTIMIZER_SWITCH_JOIN_CACHE_HASHED (1ULL << 22)
#define OPTIMIZER_SWITCH_JOIN_CACHE_BKA (1ULL << 21) #define OPTIMIZER_SWITCH_JOIN_CACHE_BKA (1ULL << 23)
#define OPTIMIZER_SWITCH_OPTIMIZE_JOIN_BUFFER_SIZE (1ULL << 22) #define OPTIMIZER_SWITCH_OPTIMIZE_JOIN_BUFFER_SIZE (1ULL << 24)
#ifdef DBUG_OFF #ifdef DBUG_OFF
# define OPTIMIZER_SWITCH_LAST (1ULL << 23) # define OPTIMIZER_SWITCH_LAST (1ULL << 25)
#else #else
# define OPTIMIZER_SWITCH_TABLE_ELIMINATION (1ULL << 23) # define OPTIMIZER_SWITCH_TABLE_ELIMINATION (1ULL << 25)
# define OPTIMIZER_SWITCH_LAST (1ULL << 24) # define OPTIMIZER_SWITCH_LAST (1ULL << 26)
#endif #endif
#ifdef DBUG_OFF #ifdef DBUG_OFF
...@@ -612,6 +613,8 @@ enabled by default, add OPTIMIZER_SWITCH_MATERIALIZATION ...@@ -612,6 +613,8 @@ enabled by default, add OPTIMIZER_SWITCH_MATERIALIZATION
OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \ OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \
OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT | \ OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT | \
OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN | \ OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN | \
OPTIMIZER_SWITCH_DERIVED_MERGE | \
OPTIMIZER_SWITCH_DERIVED_WITH_KEYS | \
OPTIMIZER_SWITCH_FIRSTMATCH | \ OPTIMIZER_SWITCH_FIRSTMATCH | \
OPTIMIZER_SWITCH_LOOSE_SCAN | \ OPTIMIZER_SWITCH_LOOSE_SCAN | \
OPTIMIZER_SWITCH_IN_TO_EXISTS | \ OPTIMIZER_SWITCH_IN_TO_EXISTS | \
...@@ -632,6 +635,8 @@ enabled by default, add OPTIMIZER_SWITCH_MATERIALIZATION ...@@ -632,6 +635,8 @@ enabled by default, add OPTIMIZER_SWITCH_MATERIALIZATION
OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \ OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \
OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT | \ OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT | \
OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN | \ OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN | \
OPTIMIZER_SWITCH_DERIVED_MERGE | \
OPTIMIZER_SWITCH_DERIVED_WITH_KEYS | \
OPTIMIZER_SWITCH_TABLE_ELIMINATION | \ OPTIMIZER_SWITCH_TABLE_ELIMINATION | \
OPTIMIZER_SWITCH_FIRSTMATCH | \ OPTIMIZER_SWITCH_FIRSTMATCH | \
OPTIMIZER_SWITCH_LOOSE_SCAN | \ OPTIMIZER_SWITCH_LOOSE_SCAN | \
......
...@@ -336,6 +336,7 @@ static const char *optimizer_switch_names[]= ...@@ -336,6 +336,7 @@ static const char *optimizer_switch_names[]=
"index_merge","index_merge_union","index_merge_sort_union", "index_merge","index_merge_union","index_merge_sort_union",
"index_merge_intersection","index_merge_sort_intersection", "index_merge_intersection","index_merge_sort_intersection",
"index_condition_pushdown", "index_condition_pushdown",
"derived_merge", "derived_with_keys",
"firstmatch","loosescan","materialization","in_to_exists","semijoin", "firstmatch","loosescan","materialization","in_to_exists","semijoin",
"partial_match_rowid_merge", "partial_match_rowid_merge",
"partial_match_table_scan", "partial_match_table_scan",
...@@ -364,6 +365,8 @@ static const unsigned int optimizer_switch_names_len[]= ...@@ -364,6 +365,8 @@ static const unsigned int optimizer_switch_names_len[]=
sizeof("index_merge_intersection") - 1, sizeof("index_merge_intersection") - 1,
sizeof("index_merge_sort_intersection") - 1, sizeof("index_merge_sort_intersection") - 1,
sizeof("index_condition_pushdown") - 1, sizeof("index_condition_pushdown") - 1,
sizeof("derived_merge") - 1,
sizeof("derived_with_keys") - 1,
sizeof("firstmatch") - 1, sizeof("firstmatch") - 1,
sizeof("loosescan") - 1, sizeof("loosescan") - 1,
sizeof("materialization") - 1, sizeof("materialization") - 1,
...@@ -483,6 +486,8 @@ static const char *optimizer_switch_str="index_merge=on,index_merge_union=on," ...@@ -483,6 +486,8 @@ static const char *optimizer_switch_str="index_merge=on,index_merge_union=on,"
"index_merge_intersection=on," "index_merge_intersection=on,"
"index_merge_sort_intersection=off," "index_merge_sort_intersection=off,"
"index_condition_pushdown=on," "index_condition_pushdown=on,"
"derived_merge=on,"
"derived_with_keys=on,"
"firstmatch=on," "firstmatch=on,"
"loosescan=on," "loosescan=on,"
"materialization=off," "materialization=off,"
...@@ -7545,8 +7550,9 @@ each time the SQL thread starts.", ...@@ -7545,8 +7550,9 @@ each time the SQL thread starts.",
{"optimizer_switch", OPT_OPTIMIZER_SWITCH, {"optimizer_switch", OPT_OPTIMIZER_SWITCH,
"optimizer_switch=option=val[,option=val...], where option={index_merge, " "optimizer_switch=option=val[,option=val...], where option={index_merge, "
"index_merge_union, index_merge_sort_union, index_merge_intersection, " "index_merge_union, index_merge_sort_union, index_merge_intersection, "
"index_merge_sort_intersection, " "index_merge_sort_intersection, index_condition_pushdown, "
"index_condition_pushdown, firstmatch, loosescan, materialization, in_to_exists, " "derived_merge, derived_with_keys, "
"firstmatch, loosescan, materialization, in_to_exists, "
"semijoin, partial_match_rowid_merge, partial_match_table_scan, " "semijoin, partial_match_rowid_merge, partial_match_table_scan, "
"subquery_cache, outer_join_with_cache, semijoin_with_cache, " "subquery_cache, outer_join_with_cache, semijoin_with_cache, "
"join_cache_incremental, join_cache_hashed, join_cache_bka, " "join_cache_incremental, join_cache_hashed, join_cache_bka, "
......
...@@ -57,7 +57,7 @@ static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse, ...@@ -57,7 +57,7 @@ static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,
uint tables, COND *conds, uint tables, COND *conds,
table_map table_map, SELECT_LEX *select_lex, table_map table_map, SELECT_LEX *select_lex,
st_sargable_param **sargables); st_sargable_param **sargables);
static bool sort_and_filter_keyuse(DYNAMIC_ARRAY *keyuse, static bool sort_and_filter_keyuse(THD *thd, DYNAMIC_ARRAY *keyuse,
bool skip_unprefixed_keyparts); bool skip_unprefixed_keyparts);
static int sort_keyuse(KEYUSE *a,KEYUSE *b); static int sort_keyuse(KEYUSE *a,KEYUSE *b);
static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
...@@ -1103,7 +1103,8 @@ JOIN::optimize() ...@@ -1103,7 +1103,8 @@ JOIN::optimize()
DBUG_RETURN(1); DBUG_RETURN(1);
} }
drop_unused_derived_keys(); if (optimizer_flag(thd, OPTIMIZER_SWITCH_DERIVED_WITH_KEYS))
drop_unused_derived_keys();
if (rollup.state != ROLLUP::STATE_NONE) if (rollup.state != ROLLUP::STATE_NONE)
{ {
...@@ -3152,7 +3153,8 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list, ...@@ -3152,7 +3153,8 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
((Item_in_subselect*)join->unit->item)->in_strategy & SUBS_IN_TO_EXISTS); ((Item_in_subselect*)join->unit->item)->in_strategy & SUBS_IN_TO_EXISTS);
if (keyuse_array->elements && if (keyuse_array->elements &&
sort_and_filter_keyuse(keyuse_array, skip_unprefixed_keyparts)) sort_and_filter_keyuse(join->thd, keyuse_array,
skip_unprefixed_keyparts))
goto error; goto error;
DBUG_EXECUTE("opt", print_keyuse_array(keyuse_array);); DBUG_EXECUTE("opt", print_keyuse_array(keyuse_array););
} }
...@@ -4654,7 +4656,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, ...@@ -4654,7 +4656,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
Special treatment for ft-keys. Special treatment for ft-keys.
*/ */
static bool sort_and_filter_keyuse(DYNAMIC_ARRAY *keyuse, static bool sort_and_filter_keyuse(THD *thd, DYNAMIC_ARRAY *keyuse,
bool skip_unprefixed_keyparts) bool skip_unprefixed_keyparts)
{ {
KEYUSE key_end, *prev, *save_pos, *use; KEYUSE key_end, *prev, *save_pos, *use;
...@@ -4669,7 +4671,8 @@ static bool sort_and_filter_keyuse(DYNAMIC_ARRAY *keyuse, ...@@ -4669,7 +4671,8 @@ static bool sort_and_filter_keyuse(DYNAMIC_ARRAY *keyuse,
if (insert_dynamic(keyuse, (uchar*) &key_end)) if (insert_dynamic(keyuse, (uchar*) &key_end))
return TRUE; return TRUE;
generate_derived_keys(keyuse); if (optimizer_flag(thd, OPTIMIZER_SWITCH_DERIVED_WITH_KEYS))
generate_derived_keys(keyuse);
use= save_pos= dynamic_element(keyuse,0,KEYUSE*); use= save_pos= dynamic_element(keyuse,0,KEYUSE*);
prev= &key_end; prev= &key_end;
...@@ -21432,7 +21435,7 @@ JOIN::reoptimize(Item *added_where, table_map join_tables, ...@@ -21432,7 +21435,7 @@ JOIN::reoptimize(Item *added_where, table_map join_tables,
/* added_keyuse contents is copied, and it is no longer needed. */ /* added_keyuse contents is copied, and it is no longer needed. */
delete_dynamic(&added_keyuse); delete_dynamic(&added_keyuse);
if (sort_and_filter_keyuse(&keyuse, true)) if (sort_and_filter_keyuse(thd, &keyuse, true))
return REOPT_ERROR; return REOPT_ERROR;
optimize_keyuse(this, &keyuse); optimize_keyuse(this, &keyuse);
......
...@@ -5869,8 +5869,9 @@ bool TABLE_LIST::init_derived(THD *thd, bool init_view) ...@@ -5869,8 +5869,9 @@ bool TABLE_LIST::init_derived(THD *thd, bool init_view)
{ {
/* A subquery might be forced to be materialized due to a side-effect. */ /* A subquery might be forced to be materialized due to a side-effect. */
if (!is_materialized_derived() && first_select->is_mergeable() && if (!is_materialized_derived() && first_select->is_mergeable() &&
optimizer_flag(thd, OPTIMIZER_SWITCH_DERIVED_MERGE) &&
!(thd->lex->sql_command == SQLCOM_UPDATE_MULTI || !(thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
thd->lex->sql_command == SQLCOM_UPDATE)) thd->lex->sql_command == SQLCOM_DELETE_MULTI))
set_merged_derived(); set_merged_derived();
else else
set_materialized_derived(); set_materialized_derived();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment