mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-30812: Improve output cardinality estimates for hash join
Introduce @@optimizer_switch flag: hash_join_cardinality When it is on, use EITS statistics to produce tighter bounds for hash join output cardinality. Amended by Monty. Reviewed by: Monty <monty@mariadb.org>
This commit is contained in:
105
mysql-test/main/join_cache_cardinality.result
Normal file
105
mysql-test/main/join_cache_cardinality.result
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
create table t1 (a int, b int, c int);
|
||||||
|
insert into t1 select seq,seq/2, seq/4 from seq_1_to_100;
|
||||||
|
create table t2 (a int, b int, c int);
|
||||||
|
insert into t2 select seq, seq/2, seq/4 from seq_1_to_200;
|
||||||
|
analyze table t1,t2 persistent for all;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 analyze status Engine-independent statistics collected
|
||||||
|
test.t1 analyze status OK
|
||||||
|
test.t2 analyze status Engine-independent statistics collected
|
||||||
|
test.t2 analyze status OK
|
||||||
|
set optimizer_trace=1;
|
||||||
|
set join_cache_level=6;
|
||||||
|
set optimizer_switch='hash_join_cardinality=on';
|
||||||
|
explain select *
|
||||||
|
from t1, t2
|
||||||
|
where t1.a=t2.a and t1.a=t2.b and t1.c=t2.c;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 100 Using where
|
||||||
|
1 SIMPLE t2 hash_ALL NULL #hash#$hj 15 test.t1.a,test.t1.a,test.t1.c 200 Using where; Using join buffer (flat, BNLH join)
|
||||||
|
set @json= (select trace from information_schema.optimizer_trace);
|
||||||
|
select json_detailed(json_extract(@json, '$**.hash_join_cardinality')) as JS;
|
||||||
|
JS
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"hash_join_columns":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"field": "a",
|
||||||
|
"avg_frequency": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "b",
|
||||||
|
"avg_frequency": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "c",
|
||||||
|
"avg_frequency": 3.9216
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rows": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
select json_detailed(json_extract(@json, '$**.rest_of_plan[*].rows_for_plan'))
|
||||||
|
as ROWS_FOR_PLAN;
|
||||||
|
ROWS_FOR_PLAN
|
||||||
|
[100]
|
||||||
|
explain select *
|
||||||
|
from t1, t2 where t1.c=t2.c;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 100 Using where
|
||||||
|
1 SIMPLE t2 hash_ALL NULL #hash#$hj 5 test.t1.c 200 Using where; Using join buffer (flat, BNLH join)
|
||||||
|
set @json= (select trace from information_schema.optimizer_trace);
|
||||||
|
select json_detailed(json_extract(@json, '$**.hash_join_cardinality')) as JS;
|
||||||
|
JS
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"hash_join_columns":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"field": "c",
|
||||||
|
"avg_frequency": 3.9216
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rows": 3.9216
|
||||||
|
}
|
||||||
|
]
|
||||||
|
select json_detailed(json_extract(@json, '$**.rest_of_plan[*].rows_for_plan'))
|
||||||
|
as ROWS_FOR_PLAN;
|
||||||
|
ROWS_FOR_PLAN
|
||||||
|
[392.16]
|
||||||
|
explain select *
|
||||||
|
from t1 straight_join t2 where t1.c=t2.c and t2.a<30;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 100 Using where
|
||||||
|
1 SIMPLE t2 hash_ALL NULL #hash#$hj 5 test.t1.c 200 Using where; Using join buffer (flat, BNLH join)
|
||||||
|
set @json= (select trace from information_schema.optimizer_trace);
|
||||||
|
# Note that rows is the same:
|
||||||
|
select json_detailed(json_extract(@json, '$**.hash_join_cardinality')) as JS;
|
||||||
|
JS
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"hash_join_columns":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"field": "c",
|
||||||
|
"avg_frequency": 3.9216
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rows": 3.9216
|
||||||
|
}
|
||||||
|
]
|
||||||
|
# Despite available selectivity:
|
||||||
|
select json_detailed(json_extract(@json, '$**.selectivity_for_columns')) as JS;
|
||||||
|
JS
|
||||||
|
[
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"column_name": "a",
|
||||||
|
"ranges":
|
||||||
|
["NULL < a < 30"],
|
||||||
|
"selectivity_from_histogram": 0.1484375
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
drop table t1,t2;
|
41
mysql-test/main/join_cache_cardinality.test
Normal file
41
mysql-test/main/join_cache_cardinality.test
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
--source include/have_sequence.inc
|
||||||
|
|
||||||
|
# Embedded doesn't have optimizer trace:
|
||||||
|
--source include/not_embedded.inc
|
||||||
|
|
||||||
|
create table t1 (a int, b int, c int);
|
||||||
|
insert into t1 select seq,seq/2, seq/4 from seq_1_to_100;
|
||||||
|
|
||||||
|
create table t2 (a int, b int, c int);
|
||||||
|
insert into t2 select seq, seq/2, seq/4 from seq_1_to_200;
|
||||||
|
|
||||||
|
analyze table t1,t2 persistent for all;
|
||||||
|
|
||||||
|
set optimizer_trace=1;
|
||||||
|
set join_cache_level=6;
|
||||||
|
set optimizer_switch='hash_join_cardinality=on';
|
||||||
|
explain select *
|
||||||
|
from t1, t2
|
||||||
|
where t1.a=t2.a and t1.a=t2.b and t1.c=t2.c;
|
||||||
|
|
||||||
|
set @json= (select trace from information_schema.optimizer_trace);
|
||||||
|
select json_detailed(json_extract(@json, '$**.hash_join_cardinality')) as JS;
|
||||||
|
select json_detailed(json_extract(@json, '$**.rest_of_plan[*].rows_for_plan'))
|
||||||
|
as ROWS_FOR_PLAN;
|
||||||
|
|
||||||
|
explain select *
|
||||||
|
from t1, t2 where t1.c=t2.c;
|
||||||
|
set @json= (select trace from information_schema.optimizer_trace);
|
||||||
|
select json_detailed(json_extract(@json, '$**.hash_join_cardinality')) as JS;
|
||||||
|
select json_detailed(json_extract(@json, '$**.rest_of_plan[*].rows_for_plan'))
|
||||||
|
as ROWS_FOR_PLAN;
|
||||||
|
|
||||||
|
explain select *
|
||||||
|
from t1 straight_join t2 where t1.c=t2.c and t2.a<30;
|
||||||
|
set @json= (select trace from information_schema.optimizer_trace);
|
||||||
|
--echo # Note that rows is the same:
|
||||||
|
select json_detailed(json_extract(@json, '$**.hash_join_cardinality')) as JS;
|
||||||
|
|
||||||
|
--echo # Despite available selectivity:
|
||||||
|
select json_detailed(json_extract(@json, '$**.selectivity_for_columns')) as JS;
|
||||||
|
drop table t1,t2;
|
@ -734,7 +734,8 @@ The following specify which files/extra groups are read (specified before remain
|
|||||||
extended_keys, exists_to_in, orderby_uses_equalities,
|
extended_keys, exists_to_in, orderby_uses_equalities,
|
||||||
condition_pushdown_for_derived, split_materialized,
|
condition_pushdown_for_derived, split_materialized,
|
||||||
condition_pushdown_for_subquery, rowid_filter,
|
condition_pushdown_for_subquery, rowid_filter,
|
||||||
condition_pushdown_from_having, not_null_range_scan
|
condition_pushdown_from_having, not_null_range_scan,
|
||||||
|
hash_join_cardinality
|
||||||
--optimizer-trace=name
|
--optimizer-trace=name
|
||||||
Controls tracing of the Optimizer:
|
Controls tracing of the Optimizer:
|
||||||
optimizer_trace=option=val[,option=val...], where option
|
optimizer_trace=option=val[,option=val...], where option
|
||||||
|
@ -38,7 +38,7 @@ SET @@session.session_track_system_variables='optimizer_switch';
|
|||||||
set optimizer_switch='index_merge=off,index_merge_union=off,index_merge_sort_union=off,index_merge_intersection=off,index_merge_sort_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=on,mrr_cost_based=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=on,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off';
|
set optimizer_switch='index_merge=off,index_merge_union=off,index_merge_sort_union=off,index_merge_intersection=off,index_merge_sort_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=on,mrr_cost_based=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=on,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off';
|
||||||
-- Tracker : SESSION_TRACK_SYSTEM_VARIABLES
|
-- Tracker : SESSION_TRACK_SYSTEM_VARIABLES
|
||||||
-- optimizer_switch
|
-- optimizer_switch
|
||||||
-- index_merge=off,index_merge_union=off,index_merge_sort_union=off,index_merge_intersection=off,index_merge_sort_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=on,mrr_cost_based=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=on,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off
|
-- index_merge=off,index_merge_union=off,index_merge_sort_union=off,index_merge_intersection=off,index_merge_sort_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=on,mrr_cost_based=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=on,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=off
|
||||||
|
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1681 'engine_condition_pushdown=on' is deprecated and will be removed in a future release
|
Warning 1681 'engine_condition_pushdown=on' is deprecated and will be removed in a future release
|
||||||
|
@ -1,60 +1,60 @@
|
|||||||
set @@global.optimizer_switch=@@optimizer_switch;
|
set @@global.optimizer_switch=@@optimizer_switch;
|
||||||
select @@global.optimizer_switch;
|
select @@global.optimizer_switch;
|
||||||
@@global.optimizer_switch
|
@@global.optimizer_switch
|
||||||
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off
|
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=off
|
||||||
select @@session.optimizer_switch;
|
select @@session.optimizer_switch;
|
||||||
@@session.optimizer_switch
|
@@session.optimizer_switch
|
||||||
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off
|
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=off
|
||||||
show global variables like 'optimizer_switch';
|
show global variables like 'optimizer_switch';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off
|
optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=off
|
||||||
show session variables like 'optimizer_switch';
|
show session variables like 'optimizer_switch';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off
|
optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=off
|
||||||
select * from information_schema.global_variables where variable_name='optimizer_switch';
|
select * from information_schema.global_variables where variable_name='optimizer_switch';
|
||||||
VARIABLE_NAME VARIABLE_VALUE
|
VARIABLE_NAME VARIABLE_VALUE
|
||||||
OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off
|
OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=off
|
||||||
select * from information_schema.session_variables where variable_name='optimizer_switch';
|
select * from information_schema.session_variables where variable_name='optimizer_switch';
|
||||||
VARIABLE_NAME VARIABLE_VALUE
|
VARIABLE_NAME VARIABLE_VALUE
|
||||||
OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off
|
OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=off
|
||||||
set global optimizer_switch=4101;
|
set global optimizer_switch=4101;
|
||||||
set session optimizer_switch=2058;
|
set session optimizer_switch=2058;
|
||||||
select @@global.optimizer_switch;
|
select @@global.optimizer_switch;
|
||||||
@@global.optimizer_switch
|
@@global.optimizer_switch
|
||||||
index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off
|
index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off
|
||||||
select @@session.optimizer_switch;
|
select @@session.optimizer_switch;
|
||||||
@@session.optimizer_switch
|
@@session.optimizer_switch
|
||||||
index_merge=off,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off
|
index_merge=off,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off
|
||||||
set global optimizer_switch="index_merge_sort_union=on";
|
set global optimizer_switch="index_merge_sort_union=on";
|
||||||
set session optimizer_switch="index_merge=off";
|
set session optimizer_switch="index_merge=off";
|
||||||
select @@global.optimizer_switch;
|
select @@global.optimizer_switch;
|
||||||
@@global.optimizer_switch
|
@@global.optimizer_switch
|
||||||
index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off
|
index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off
|
||||||
select @@session.optimizer_switch;
|
select @@session.optimizer_switch;
|
||||||
@@session.optimizer_switch
|
@@session.optimizer_switch
|
||||||
index_merge=off,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off
|
index_merge=off,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off
|
||||||
show global variables like 'optimizer_switch';
|
show global variables like 'optimizer_switch';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
optimizer_switch index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off
|
optimizer_switch index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off
|
||||||
show session variables like 'optimizer_switch';
|
show session variables like 'optimizer_switch';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
optimizer_switch index_merge=off,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off
|
optimizer_switch index_merge=off,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off
|
||||||
select * from information_schema.global_variables where variable_name='optimizer_switch';
|
select * from information_schema.global_variables where variable_name='optimizer_switch';
|
||||||
VARIABLE_NAME VARIABLE_VALUE
|
VARIABLE_NAME VARIABLE_VALUE
|
||||||
OPTIMIZER_SWITCH index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off
|
OPTIMIZER_SWITCH index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off
|
||||||
select * from information_schema.session_variables where variable_name='optimizer_switch';
|
select * from information_schema.session_variables where variable_name='optimizer_switch';
|
||||||
VARIABLE_NAME VARIABLE_VALUE
|
VARIABLE_NAME VARIABLE_VALUE
|
||||||
OPTIMIZER_SWITCH index_merge=off,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off
|
OPTIMIZER_SWITCH index_merge=off,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off
|
||||||
set session optimizer_switch="default";
|
set session optimizer_switch="default";
|
||||||
select @@session.optimizer_switch;
|
select @@session.optimizer_switch;
|
||||||
@@session.optimizer_switch
|
@@session.optimizer_switch
|
||||||
index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off
|
index_merge=on,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=off,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=off,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=off,condition_pushdown_for_subquery=off,rowid_filter=off,condition_pushdown_from_having=off,not_null_range_scan=off,hash_join_cardinality=off
|
||||||
set optimizer_switch = replace(@@optimizer_switch, '=off', '=on');
|
set optimizer_switch = replace(@@optimizer_switch, '=off', '=on');
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1681 'engine_condition_pushdown=on' is deprecated and will be removed in a future release
|
Warning 1681 'engine_condition_pushdown=on' is deprecated and will be removed in a future release
|
||||||
select @@optimizer_switch;
|
select @@optimizer_switch;
|
||||||
@@optimizer_switch
|
@@optimizer_switch
|
||||||
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=on,mrr_sort_keys=on,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=on
|
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=on,mrr_sort_keys=on,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on,table_elimination=on,extended_keys=on,exists_to_in=on,orderby_uses_equalities=on,condition_pushdown_for_derived=on,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=on,hash_join_cardinality=on
|
||||||
set global optimizer_switch=1.1;
|
set global optimizer_switch=1.1;
|
||||||
ERROR 42000: Incorrect argument type to variable 'optimizer_switch'
|
ERROR 42000: Incorrect argument type to variable 'optimizer_switch'
|
||||||
set global optimizer_switch=1e1;
|
set global optimizer_switch=1e1;
|
||||||
|
@ -2299,7 +2299,7 @@ VARIABLE_COMMENT Fine-tune the optimizer behavior
|
|||||||
NUMERIC_MIN_VALUE NULL
|
NUMERIC_MIN_VALUE NULL
|
||||||
NUMERIC_MAX_VALUE NULL
|
NUMERIC_MAX_VALUE NULL
|
||||||
NUMERIC_BLOCK_SIZE NULL
|
NUMERIC_BLOCK_SIZE NULL
|
||||||
ENUM_VALUE_LIST index_merge,index_merge_union,index_merge_sort_union,index_merge_intersection,index_merge_sort_intersection,engine_condition_pushdown,index_condition_pushdown,derived_merge,derived_with_keys,firstmatch,loosescan,materialization,in_to_exists,semijoin,partial_match_rowid_merge,partial_match_table_scan,subquery_cache,mrr,mrr_cost_based,mrr_sort_keys,outer_join_with_cache,semijoin_with_cache,join_cache_incremental,join_cache_hashed,join_cache_bka,optimize_join_buffer_size,table_elimination,extended_keys,exists_to_in,orderby_uses_equalities,condition_pushdown_for_derived,split_materialized,condition_pushdown_for_subquery,rowid_filter,condition_pushdown_from_having,not_null_range_scan,default
|
ENUM_VALUE_LIST index_merge,index_merge_union,index_merge_sort_union,index_merge_intersection,index_merge_sort_intersection,engine_condition_pushdown,index_condition_pushdown,derived_merge,derived_with_keys,firstmatch,loosescan,materialization,in_to_exists,semijoin,partial_match_rowid_merge,partial_match_table_scan,subquery_cache,mrr,mrr_cost_based,mrr_sort_keys,outer_join_with_cache,semijoin_with_cache,join_cache_incremental,join_cache_hashed,join_cache_bka,optimize_join_buffer_size,table_elimination,extended_keys,exists_to_in,orderby_uses_equalities,condition_pushdown_for_derived,split_materialized,condition_pushdown_for_subquery,rowid_filter,condition_pushdown_from_having,not_null_range_scan,hash_join_cardinality,default
|
||||||
READ_ONLY NO
|
READ_ONLY NO
|
||||||
COMMAND_LINE_ARGUMENT REQUIRED
|
COMMAND_LINE_ARGUMENT REQUIRED
|
||||||
VARIABLE_NAME OPTIMIZER_TRACE
|
VARIABLE_NAME OPTIMIZER_TRACE
|
||||||
|
@ -2459,7 +2459,7 @@ VARIABLE_COMMENT Fine-tune the optimizer behavior
|
|||||||
NUMERIC_MIN_VALUE NULL
|
NUMERIC_MIN_VALUE NULL
|
||||||
NUMERIC_MAX_VALUE NULL
|
NUMERIC_MAX_VALUE NULL
|
||||||
NUMERIC_BLOCK_SIZE NULL
|
NUMERIC_BLOCK_SIZE NULL
|
||||||
ENUM_VALUE_LIST index_merge,index_merge_union,index_merge_sort_union,index_merge_intersection,index_merge_sort_intersection,engine_condition_pushdown,index_condition_pushdown,derived_merge,derived_with_keys,firstmatch,loosescan,materialization,in_to_exists,semijoin,partial_match_rowid_merge,partial_match_table_scan,subquery_cache,mrr,mrr_cost_based,mrr_sort_keys,outer_join_with_cache,semijoin_with_cache,join_cache_incremental,join_cache_hashed,join_cache_bka,optimize_join_buffer_size,table_elimination,extended_keys,exists_to_in,orderby_uses_equalities,condition_pushdown_for_derived,split_materialized,condition_pushdown_for_subquery,rowid_filter,condition_pushdown_from_having,not_null_range_scan,default
|
ENUM_VALUE_LIST index_merge,index_merge_union,index_merge_sort_union,index_merge_intersection,index_merge_sort_intersection,engine_condition_pushdown,index_condition_pushdown,derived_merge,derived_with_keys,firstmatch,loosescan,materialization,in_to_exists,semijoin,partial_match_rowid_merge,partial_match_table_scan,subquery_cache,mrr,mrr_cost_based,mrr_sort_keys,outer_join_with_cache,semijoin_with_cache,join_cache_incremental,join_cache_hashed,join_cache_bka,optimize_join_buffer_size,table_elimination,extended_keys,exists_to_in,orderby_uses_equalities,condition_pushdown_for_derived,split_materialized,condition_pushdown_for_subquery,rowid_filter,condition_pushdown_from_having,not_null_range_scan,hash_join_cardinality,default
|
||||||
READ_ONLY NO
|
READ_ONLY NO
|
||||||
COMMAND_LINE_ARGUMENT REQUIRED
|
COMMAND_LINE_ARGUMENT REQUIRED
|
||||||
VARIABLE_NAME OPTIMIZER_TRACE
|
VARIABLE_NAME OPTIMIZER_TRACE
|
||||||
|
@ -234,6 +234,7 @@
|
|||||||
#define OPTIMIZER_SWITCH_USE_ROWID_FILTER (1ULL << 33)
|
#define OPTIMIZER_SWITCH_USE_ROWID_FILTER (1ULL << 33)
|
||||||
#define OPTIMIZER_SWITCH_COND_PUSHDOWN_FROM_HAVING (1ULL << 34)
|
#define OPTIMIZER_SWITCH_COND_PUSHDOWN_FROM_HAVING (1ULL << 34)
|
||||||
#define OPTIMIZER_SWITCH_NOT_NULL_RANGE_SCAN (1ULL << 35)
|
#define OPTIMIZER_SWITCH_NOT_NULL_RANGE_SCAN (1ULL << 35)
|
||||||
|
#define OPTIMIZER_SWITCH_HASH_JOIN_CARDINALITY (1ULL << 36)
|
||||||
|
|
||||||
#define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
|
#define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
|
||||||
OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
|
OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
|
||||||
|
@ -7597,20 +7597,28 @@ void set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key)
|
|||||||
Estimate how many records we will get if we read just this table and apply
|
Estimate how many records we will get if we read just this table and apply
|
||||||
a part of WHERE that can be checked for it.
|
a part of WHERE that can be checked for it.
|
||||||
|
|
||||||
|
@param s Current JOIN_TAB
|
||||||
|
@param use_cond_selectivity Value of optimizer_use_condition_selectivity.
|
||||||
|
If > 1 then use table->cond_selecitivity.
|
||||||
|
@param force_estiamte Set to 1 if we should not call
|
||||||
|
use_found_constraint. To be deleted in 11.0
|
||||||
|
@return 0.0 No matching rows
|
||||||
|
@return >= 1.0 Number of expected matching rows
|
||||||
|
|
||||||
@detail
|
@detail
|
||||||
Estimate how many records we will get if we
|
Estimate how many records we will get if we
|
||||||
- read the given table with its "independent" access method (either quick
|
- read the given table with its "independent" access method (either quick
|
||||||
select or full table/index scan),
|
select or full table/index scan),
|
||||||
- apply the part of WHERE that refers only to this table.
|
- apply the part of WHERE that refers only to this table.
|
||||||
|
|
||||||
@seealso
|
@see also
|
||||||
table_cond_selectivity() produces selectivity of condition that is checked
|
table_cond_selectivity() produces selectivity of condition that is checked
|
||||||
after joining rows from this table to rows from preceding tables.
|
after joining rows from this table to rows from preceding tables.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
inline
|
static double apply_selectivity_for_table(JOIN_TAB *s,
|
||||||
double matching_candidates_in_table(JOIN_TAB *s, bool with_found_constraint,
|
uint use_cond_selectivity,
|
||||||
uint use_cond_selectivity)
|
bool *force_estimate)
|
||||||
{
|
{
|
||||||
ha_rows records;
|
ha_rows records;
|
||||||
double dbl_records;
|
double dbl_records;
|
||||||
@ -7621,34 +7629,47 @@ double matching_candidates_in_table(JOIN_TAB *s, bool with_found_constraint,
|
|||||||
double sel= table->cond_selectivity;
|
double sel= table->cond_selectivity;
|
||||||
double table_records= rows2double(s->records);
|
double table_records= rows2double(s->records);
|
||||||
dbl_records= table_records * sel;
|
dbl_records= table_records * sel;
|
||||||
|
*force_estimate= 1; // Don't call use_found_constraint()
|
||||||
return dbl_records;
|
return dbl_records;
|
||||||
}
|
}
|
||||||
|
|
||||||
records = s->found_records;
|
records = s->found_records;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If there is a filtering condition on the table (i.e. ref analyzer found
|
If applicable, get a more accurate estimate.
|
||||||
at least one "table.keyXpartY= exprZ", where exprZ refers only to tables
|
|
||||||
preceding this table in the join order we're now considering), then
|
|
||||||
assume that 25% of the rows will be filtered out by this condition.
|
|
||||||
|
|
||||||
This heuristic is supposed to force tables used in exprZ to be before
|
|
||||||
this table in join order.
|
|
||||||
*/
|
*/
|
||||||
if (with_found_constraint)
|
DBUG_ASSERT(s->table->opt_range_condition_rows <= s->found_records);
|
||||||
records-= records/4;
|
|
||||||
|
|
||||||
/*
|
|
||||||
If applicable, get a more accurate estimate. Don't use the two
|
|
||||||
heuristics at once.
|
|
||||||
*/
|
|
||||||
if (s->table->opt_range_condition_rows != s->found_records)
|
if (s->table->opt_range_condition_rows != s->found_records)
|
||||||
|
{
|
||||||
|
*force_estimate= 1; // Don't call use_found_constraint()
|
||||||
records= s->table->opt_range_condition_rows;
|
records= s->table->opt_range_condition_rows;
|
||||||
|
}
|
||||||
|
|
||||||
dbl_records= (double)records;
|
dbl_records= (double)records;
|
||||||
return dbl_records;
|
return dbl_records;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Take into account that the table's WHERE clause has conditions on earlier
|
||||||
|
tables that can reduce the number of accepted rows.
|
||||||
|
|
||||||
|
@param records Number of original rows (after selectivity)
|
||||||
|
|
||||||
|
If there is a filtering condition on the table (i.e. ref analyzer found
|
||||||
|
at least one "table.keyXpartY= exprZ", where exprZ refers only to tables
|
||||||
|
preceding this table in the join order we're now considering), then
|
||||||
|
assume that 25% of the rows will be filtered out by this condition.
|
||||||
|
|
||||||
|
This heuristic is supposed to force tables used in exprZ to be before
|
||||||
|
this table in join order.
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline double use_found_constraint(double records)
|
||||||
|
{
|
||||||
|
records-= records/4;
|
||||||
|
return records;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Calculate the cost of reading a set of rows trough an index
|
Calculate the cost of reading a set of rows trough an index
|
||||||
@ -7705,6 +7726,92 @@ double adjust_quick_cost(double quick_cost, ha_rows records)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@brief
|
||||||
|
Compute the fanout of hash join operation using EITS data
|
||||||
|
*/
|
||||||
|
|
||||||
|
double hash_join_fanout(JOIN *join, JOIN_TAB *s, table_map remaining_tables,
|
||||||
|
double rnd_records, KEYUSE *hj_start_key,
|
||||||
|
bool *stats_found)
|
||||||
|
{
|
||||||
|
THD *thd= join->thd;
|
||||||
|
/*
|
||||||
|
Before doing the hash join, we will scan the table and apply the local part
|
||||||
|
of the WHERE condition. This will produce rnd_records.
|
||||||
|
|
||||||
|
The EITS statistics describes the entire table. Calling
|
||||||
|
|
||||||
|
table->field[N]->get_avg_frequency()
|
||||||
|
|
||||||
|
produces average #rows in the table with some value.
|
||||||
|
|
||||||
|
What happens if we filter out rows so that rnd_records rows are left?
|
||||||
|
Something between the two outcomes:
|
||||||
|
A. filtering removes a fraction of rows for each value:
|
||||||
|
avg_frequency=avg_frequency * condition_selectivity
|
||||||
|
|
||||||
|
B. filtering removes entire groups of rows with the same value, but
|
||||||
|
the remaining groups remain of the same size.
|
||||||
|
|
||||||
|
We make pessimistic assumption and assume B.
|
||||||
|
We also handle an edge case: if rnd_records is less than avg_frequency,
|
||||||
|
assume we'll get rnd_records rows with the same value, and return
|
||||||
|
rnd_records as the fanout estimate.
|
||||||
|
*/
|
||||||
|
double min_freq= rnd_records;
|
||||||
|
|
||||||
|
Json_writer_object trace_obj(thd, "hash_join_cardinality");
|
||||||
|
/*
|
||||||
|
There can be multiple KEYUSE referring to same or different columns
|
||||||
|
|
||||||
|
KEYUSE(tbl.col1 = ...)
|
||||||
|
KEYUSE(tbl.col1 = ...)
|
||||||
|
KEYUSE(tbl.col2 = ...)
|
||||||
|
|
||||||
|
Hash join code can use multiple columns: (col1, col2) for joining.
|
||||||
|
We need n_distinct({col1, col2}).
|
||||||
|
|
||||||
|
EITS only has statistics on individual columns: n_distinct(col1),
|
||||||
|
n_distinct(col2).
|
||||||
|
|
||||||
|
Our current solution is to be very conservative and use selectivity
|
||||||
|
of one column with the lowest avg_frequency.
|
||||||
|
|
||||||
|
In the future, we should an approach that cautiosly takes into account
|
||||||
|
multiple KEYUSEs either multiply by number of equalities or by sqrt
|
||||||
|
of the second most selective equality.
|
||||||
|
*/
|
||||||
|
Json_writer_array trace_arr(thd, "hash_join_columns");
|
||||||
|
for (KEYUSE *keyuse= hj_start_key;
|
||||||
|
keyuse->table == s->table && is_hash_join_key_no(keyuse->key);
|
||||||
|
keyuse++)
|
||||||
|
{
|
||||||
|
if (!(remaining_tables & keyuse->used_tables) &&
|
||||||
|
(!keyuse->validity_ref || *keyuse->validity_ref) &&
|
||||||
|
s->access_from_tables_is_allowed(keyuse->used_tables,
|
||||||
|
join->sjm_lookup_tables))
|
||||||
|
{
|
||||||
|
Field *field= s->table->field[keyuse->keypart];
|
||||||
|
if (is_eits_usable(field))
|
||||||
|
{
|
||||||
|
double freq= field->read_stats->get_avg_frequency();
|
||||||
|
|
||||||
|
Json_writer_object trace_field(thd);
|
||||||
|
trace_field.add("field",field->field_name.str).
|
||||||
|
add("avg_frequency", freq);
|
||||||
|
if (freq < min_freq)
|
||||||
|
min_freq= freq;
|
||||||
|
*stats_found= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
trace_arr.end();
|
||||||
|
trace_obj.add("rows", min_freq);
|
||||||
|
return min_freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Find the best access path for an extension of a partial execution
|
Find the best access path for an extension of a partial execution
|
||||||
plan and add this path to the plan.
|
plan and add this path to the plan.
|
||||||
@ -8399,11 +8506,44 @@ best_access_path(JOIN *join,
|
|||||||
(!(s->table->map & join->outer_join) ||
|
(!(s->table->map & join->outer_join) ||
|
||||||
join->allowed_outer_join_with_cache)) // (2)
|
join->allowed_outer_join_with_cache)) // (2)
|
||||||
{
|
{
|
||||||
|
double fanout;
|
||||||
Json_writer_object trace_access_hash(thd);
|
Json_writer_object trace_access_hash(thd);
|
||||||
double join_sel= 0.1;
|
trace_access_hash.add("type", "hash");
|
||||||
|
trace_access_hash.add("index", "hj-key");
|
||||||
|
double join_sel;
|
||||||
|
bool stats_found= 0, force_estimate= 0;
|
||||||
/* Estimate the cost of the hash join access to the table */
|
/* Estimate the cost of the hash join access to the table */
|
||||||
double rnd_records= matching_candidates_in_table(s, found_constraint,
|
double rnd_records= apply_selectivity_for_table(s, use_cond_selectivity,
|
||||||
use_cond_selectivity);
|
&force_estimate);
|
||||||
|
|
||||||
|
DBUG_ASSERT(hj_start_key);
|
||||||
|
if (optimizer_flag(thd, OPTIMIZER_SWITCH_HASH_JOIN_CARDINALITY))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Starting from this point, rnd_records should not be used anymore.
|
||||||
|
Use "fanout" for an estimate of # matching records.
|
||||||
|
*/
|
||||||
|
fanout= hash_join_fanout(join, s, remaining_tables, rnd_records,
|
||||||
|
hj_start_key, &stats_found);
|
||||||
|
join_sel= 1.0; // Don't do the "10% heuristic"
|
||||||
|
}
|
||||||
|
if (!stats_found)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
No OPTIMIZER_SWITCH_HASH_JOIN_CARDINALITY or no field statistics
|
||||||
|
found.
|
||||||
|
|
||||||
|
Take into account if there is non constant constraints used with
|
||||||
|
earlier tables in the where expression.
|
||||||
|
If yes, this will set fanout to rnd_records/4.
|
||||||
|
We estimate that there will be HASH_FANOUT (10%)
|
||||||
|
hash matches / row.
|
||||||
|
*/
|
||||||
|
if (found_constraint && !force_estimate)
|
||||||
|
rnd_records= use_found_constraint(rnd_records);
|
||||||
|
fanout= rnd_records;
|
||||||
|
join_sel= 0.1;
|
||||||
|
}
|
||||||
|
|
||||||
tmp= s->quick ? s->quick->read_time : s->scan_time();
|
tmp= s->quick ? s->quick->read_time : s->scan_time();
|
||||||
double cmp_time= (s->records - rnd_records)/TIME_FOR_COMPARE;
|
double cmp_time= (s->records - rnd_records)/TIME_FOR_COMPARE;
|
||||||
@ -8415,19 +8555,36 @@ best_access_path(JOIN *join,
|
|||||||
record_count /
|
record_count /
|
||||||
(double) thd->variables.join_buff_size));
|
(double) thd->variables.join_buff_size));
|
||||||
tmp= COST_MULT(tmp, refills);
|
tmp= COST_MULT(tmp, refills);
|
||||||
best_time= COST_ADD(tmp,
|
|
||||||
COST_MULT((record_count*join_sel) / TIME_FOR_COMPARE,
|
// Add cost of reading/writing the join buffer
|
||||||
rnd_records));
|
if (optimizer_flag(thd, OPTIMIZER_SWITCH_HASH_JOIN_CARDINALITY))
|
||||||
|
{
|
||||||
|
/* Set it to be 1/10th of TIME_FOR_COMPARE */
|
||||||
|
double row_copy_cost= 1.0 / (10*TIME_FOR_COMPARE);
|
||||||
|
double join_buffer_operations=
|
||||||
|
COST_ADD(
|
||||||
|
COST_MULT(record_count, row_copy_cost),
|
||||||
|
COST_MULT(record_count, fanout * (idx - join->const_tables))
|
||||||
|
);
|
||||||
|
double jbuf_use_cost= row_copy_cost * join_buffer_operations;
|
||||||
|
trace_access_hash.add("jbuf_use_cost", jbuf_use_cost);
|
||||||
|
tmp= COST_ADD(tmp, jbuf_use_cost);
|
||||||
|
}
|
||||||
|
|
||||||
|
double where_cost= COST_MULT((fanout*join_sel) / TIME_FOR_COMPARE,
|
||||||
|
record_count);
|
||||||
|
trace_access_hash.add("extra_cond_check_cost", where_cost);
|
||||||
|
|
||||||
|
best_time= COST_ADD(tmp, where_cost);
|
||||||
|
|
||||||
best= tmp;
|
best= tmp;
|
||||||
records= rnd_records;
|
records= fanout;
|
||||||
best_key= hj_start_key;
|
best_key= hj_start_key;
|
||||||
best_ref_depends_map= 0;
|
best_ref_depends_map= 0;
|
||||||
best_uses_jbuf= TRUE;
|
best_uses_jbuf= TRUE;
|
||||||
best_filter= 0;
|
best_filter= 0;
|
||||||
best_type= JT_HASH;
|
best_type= JT_HASH;
|
||||||
trace_access_hash.add("type", "hash");
|
trace_access_hash.add("records", records);
|
||||||
trace_access_hash.add("index", "hj-key");
|
|
||||||
trace_access_hash.add("cost", rnd_records);
|
|
||||||
trace_access_hash.add("cost", best);
|
trace_access_hash.add("cost", best);
|
||||||
trace_access_hash.add("chosen", true);
|
trace_access_hash.add("chosen", true);
|
||||||
}
|
}
|
||||||
@ -8479,9 +8636,13 @@ best_access_path(JOIN *join,
|
|||||||
!(s->table->force_index && best_key && !s->quick) && // (4)
|
!(s->table->force_index && best_key && !s->quick) && // (4)
|
||||||
!(best_key && s->table->pos_in_table_list->jtbm_subselect)) // (5)
|
!(best_key && s->table->pos_in_table_list->jtbm_subselect)) // (5)
|
||||||
{ // Check full join
|
{ // Check full join
|
||||||
double rnd_records= matching_candidates_in_table(s, found_constraint,
|
bool force_estimate= 0;
|
||||||
use_cond_selectivity);
|
double rnd_records= apply_selectivity_for_table(s,
|
||||||
|
use_cond_selectivity,
|
||||||
|
&force_estimate);
|
||||||
|
rnd_records= ((found_constraint && !force_estimate) ?
|
||||||
|
use_found_constraint(rnd_records) :
|
||||||
|
rnd_records);
|
||||||
/*
|
/*
|
||||||
Range optimizer never proposes a RANGE if it isn't better
|
Range optimizer never proposes a RANGE if it isn't better
|
||||||
than FULL: so if RANGE is present, it's always preferred to FULL.
|
than FULL: so if RANGE is present, it's always preferred to FULL.
|
||||||
@ -9698,7 +9859,7 @@ double table_multi_eq_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
|
|||||||
with previous tables.
|
with previous tables.
|
||||||
|
|
||||||
For quick selects and full table scans, selectivity of COND(this_table)
|
For quick selects and full table scans, selectivity of COND(this_table)
|
||||||
is accounted for in matching_candidates_in_table(). Here, we only count
|
is accounted for in apply_selectivity_for_table(). Here, we only count
|
||||||
selectivity of COND(this_table, previous_tables).
|
selectivity of COND(this_table, previous_tables).
|
||||||
|
|
||||||
For other access methods, we need to calculate selectivity of the whole
|
For other access methods, we need to calculate selectivity of the whole
|
||||||
@ -9900,7 +10061,7 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
|
|||||||
/*
|
/*
|
||||||
The table is accessed with full table scan, or quick select.
|
The table is accessed with full table scan, or quick select.
|
||||||
Selectivity of COND(table) is already accounted for in
|
Selectivity of COND(table) is already accounted for in
|
||||||
matching_candidates_in_table().
|
apply_selectivity_for_table().
|
||||||
*/
|
*/
|
||||||
sel= 1;
|
sel= 1;
|
||||||
}
|
}
|
||||||
|
@ -2756,6 +2756,7 @@ export const char *optimizer_switch_names[]=
|
|||||||
"rowid_filter",
|
"rowid_filter",
|
||||||
"condition_pushdown_from_having",
|
"condition_pushdown_from_having",
|
||||||
"not_null_range_scan",
|
"not_null_range_scan",
|
||||||
|
"hash_join_cardinality",
|
||||||
"default",
|
"default",
|
||||||
NullS
|
NullS
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user