Commit fc1c8ffd authored by Igor Babaev's avatar Igor Babaev

The pilot patch for mwl#253.

parent 938d47dc
......@@ -500,6 +500,18 @@ The following options may be given as the first argument:
partial_match_table_scan, semijoin, semijoin_with_cache,
subquery_cache, table_elimination, extended_keys,
exists_to_in } and val is one of {on, off, default}
--optimizer-use-condition-selectivity=#
Controls selectivity of which conditions the optimizer
takes into account to calculate cardinality of a partial
join when it searches for the best execution plan
Meaning: 1 - use selectivity of index backed range
conditions to calculate cardinality of the partial join
if the last joined table is accessed by full table scan
or an index scan 2 - use selectivity of index backed
range conditions to calculate cardinality of the partial
join in any case 3 - additionally always use selectivity
of range conditions that are not backed by any index to
calculate cardinality of the partial join
--performance-schema
Enable the performance schema.
--performance-schema-events-waits-history-long-size=#
......@@ -1004,6 +1016,7 @@ old-style-user-limits FALSE
optimizer-prune-level 1
optimizer-search-depth 62
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=off,table_elimination=on
optimizer-use-condition-selectivity 1
performance-schema FALSE
performance-schema-events-waits-history-long-size 10000
performance-schema-events-waits-history-size 10
......
select @@global.use_stat_tables;
@@global.use_stat_tables
COMPLEMENTARY
select @@session.use_stat_tables;
@@session.use_stat_tables
COMPLEMENTARY
set @save_use_stat_tables=@@use_stat_tables;
set use_stat_tables='preferably';
DROP DATABASE IF EXISTS dbt3_s001;
CREATE DATABASE dbt3_s001;
use dbt3_s001;
set @save_optimizer_use_condition_selectivity=@@optimizer_use_condition_selectivity;
EXPLAIN EXTENDED select sql_calc_found_rows
s_name, s_address
from supplier, nation
where s_suppkey in (select ps_suppkey from partsupp
where ps_partkey in (select p_partkey from part
where p_name like 'g%')
and ps_availqty >
(select 0.5 * sum(l_quantity)
from lineitem
where l_partkey = ps_partkey
and l_suppkey = ps_suppkey
and l_shipdate >= date('1993-01-01')
and l_shipdate < date('1993-01-01') +
interval '1' year ))
and s_nationkey = n_nationkey
and n_name = 'UNITED STATES'
order by s_name
limit 10;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY supplier ALL PRIMARY,i_s_nationkey NULL NULL NULL 10 100.00 Using where; Using filesort
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
1 PRIMARY nation eq_ref PRIMARY PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 100.00 Using where
2 MATERIALIZED part ALL PRIMARY NULL NULL NULL 200 100.00 Using where
2 MATERIALIZED partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 Using where
4 DEPENDENT SUBQUERY lineitem ref i_l_shipdate,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey i_l_suppkey_partkey 10 dbt3_s001.partsupp.ps_partkey,dbt3_s001.partsupp.ps_suppkey 8 100.00 Using where
Warnings:
Note 1276 Field or reference 'dbt3_s001.partsupp.ps_partkey' of SELECT #4 was resolved in SELECT #2
Note 1276 Field or reference 'dbt3_s001.partsupp.ps_suppkey' of SELECT #4 was resolved in SELECT #2
Note 1003 select sql_calc_found_rows `dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`supplier`.`s_address` AS `s_address` from `dbt3_s001`.`supplier` semi join (`dbt3_s001`.`part` join `dbt3_s001`.`partsupp`) join `dbt3_s001`.`nation` where ((`dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey`) and (`dbt3_s001`.`nation`.`n_name` = 'UNITED STATES') and (`dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey`) and (`dbt3_s001`.`partsupp`.`ps_availqty` > <expr_cache><`dbt3_s001`.`partsupp`.`ps_partkey`,`dbt3_s001`.`partsupp`.`ps_suppkey`>((select (0.5 * sum(`dbt3_s001`.`lineitem`.`l_quantity`)) from `dbt3_s001`.`lineitem` where ((`dbt3_s001`.`lineitem`.`l_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey`) and (`dbt3_s001`.`lineitem`.`l_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey`) and (`dbt3_s001`.`lineitem`.`l_shipDATE` >= <cache>(cast('1993-01-01' as date))) and (`dbt3_s001`.`lineitem`.`l_shipDATE` < <cache>((cast('1993-01-01' as date) + interval '1' year))))))) and (`dbt3_s001`.`part`.`p_name` like 'g%')) order by `dbt3_s001`.`supplier`.`s_name` limit 10
select sql_calc_found_rows
s_name, s_address
from supplier, nation
where s_suppkey in (select ps_suppkey from partsupp
where ps_partkey in (select p_partkey from part
where p_name like 'g%')
and ps_availqty >
(select 0.5 * sum(l_quantity)
from lineitem
where l_partkey = ps_partkey
and l_suppkey = ps_suppkey
and l_shipdate >= date('1993-01-01')
and l_shipdate < date('1993-01-01') +
interval '1' year ))
and s_nationkey = n_nationkey
and n_name = 'UNITED STATES'
order by s_name
limit 10;
s_name s_address
Supplier#000000010 Saygah3gYWMp72i PY
set optimizer_use_condition_selectivity=3;
EXPLAIN EXTENDED select sql_calc_found_rows
s_name, s_address
from supplier, nation
where s_suppkey in (select ps_suppkey from partsupp
where ps_partkey in (select p_partkey from part
where p_name like 'g%')
and ps_availqty >
(select 0.5 * sum(l_quantity)
from lineitem
where l_partkey = ps_partkey
and l_suppkey = ps_suppkey
and l_shipdate >= date('1993-01-01')
and l_shipdate < date('1993-01-01') +
interval '1' year ))
and s_nationkey = n_nationkey
and n_name = 'UNITED STATES'
order by s_name
limit 10;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY nation ALL PRIMARY NULL NULL NULL 25 4.00 Using where; Using temporary; Using filesort
1 PRIMARY supplier ref PRIMARY,i_s_nationkey i_s_nationkey 5 dbt3_s001.nation.n_nationkey 1 100.00
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
2 MATERIALIZED part ALL PRIMARY NULL NULL NULL 200 4.17 Using where
2 MATERIALIZED partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 Using where
4 DEPENDENT SUBQUERY lineitem ref i_l_shipdate,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey i_l_suppkey_partkey 10 dbt3_s001.partsupp.ps_partkey,dbt3_s001.partsupp.ps_suppkey 8 100.00 Using where
Warnings:
Note 1276 Field or reference 'dbt3_s001.partsupp.ps_partkey' of SELECT #4 was resolved in SELECT #2
Note 1276 Field or reference 'dbt3_s001.partsupp.ps_suppkey' of SELECT #4 was resolved in SELECT #2
Note 1003 select sql_calc_found_rows `dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`supplier`.`s_address` AS `s_address` from `dbt3_s001`.`supplier` semi join (`dbt3_s001`.`part` join `dbt3_s001`.`partsupp`) join `dbt3_s001`.`nation` where ((`dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey`) and (`dbt3_s001`.`nation`.`n_name` = 'UNITED STATES') and (`dbt3_s001`.`supplier`.`s_nationkey` = `dbt3_s001`.`nation`.`n_nationkey`) and (`dbt3_s001`.`partsupp`.`ps_availqty` > <expr_cache><`dbt3_s001`.`partsupp`.`ps_partkey`,`dbt3_s001`.`partsupp`.`ps_suppkey`>((select (0.5 * sum(`dbt3_s001`.`lineitem`.`l_quantity`)) from `dbt3_s001`.`lineitem` where ((`dbt3_s001`.`lineitem`.`l_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey`) and (`dbt3_s001`.`lineitem`.`l_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey`) and (`dbt3_s001`.`lineitem`.`l_shipDATE` >= <cache>(cast('1993-01-01' as date))) and (`dbt3_s001`.`lineitem`.`l_shipDATE` < <cache>((cast('1993-01-01' as date) + interval '1' year))))))) and (`dbt3_s001`.`part`.`p_name` like 'g%')) order by `dbt3_s001`.`supplier`.`s_name` limit 10
select sql_calc_found_rows
s_name, s_address
from supplier, nation
where s_suppkey in (select ps_suppkey from partsupp
where ps_partkey in (select p_partkey from part
where p_name like 'g%')
and ps_availqty >
(select 0.5 * sum(l_quantity)
from lineitem
where l_partkey = ps_partkey
and l_suppkey = ps_suppkey
and l_shipdate >= date('1993-01-01')
and l_shipdate < date('1993-01-01') +
interval '1' year ))
and s_nationkey = n_nationkey
and n_name = 'UNITED STATES'
order by s_name
limit 10;
s_name s_address
Supplier#000000010 Saygah3gYWMp72i PY
DROP DATABASE dbt3_s001;
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
set use_stat_tables=@save_use_stat_tables;
SET SESSION STORAGE_ENGINE='InnoDB';
set @save_optimizer_switch_for_selectivity_test=@@optimizer_switch;
set optimizer_switch='extended_keys=on';
select @@global.use_stat_tables;
@@global.use_stat_tables
COMPLEMENTARY
select @@session.use_stat_tables;
@@session.use_stat_tables
COMPLEMENTARY
set @save_use_stat_tables=@@use_stat_tables;
set use_stat_tables='preferably';
DROP DATABASE IF EXISTS dbt3_s001;
CREATE DATABASE dbt3_s001;
use dbt3_s001;
set @save_optimizer_use_condition_selectivity=@@optimizer_use_condition_selectivity;
EXPLAIN EXTENDED select sql_calc_found_rows
s_name, s_address
from supplier, nation
where s_suppkey in (select ps_suppkey from partsupp
where ps_partkey in (select p_partkey from part
where p_name like 'g%')
and ps_availqty >
(select 0.5 * sum(l_quantity)
from lineitem
where l_partkey = ps_partkey
and l_suppkey = ps_suppkey
and l_shipdate >= date('1993-01-01')
and l_shipdate < date('1993-01-01') +
interval '1' year ))
and s_nationkey = n_nationkey
and n_name = 'UNITED STATES'
order by s_name
limit 10;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY supplier ALL PRIMARY,i_s_nationkey NULL NULL NULL 10 100.00 Using where; Using filesort
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
1 PRIMARY nation eq_ref PRIMARY PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 100.00 Using where
2 MATERIALIZED part ALL PRIMARY NULL NULL NULL 200 100.00 Using where
2 MATERIALIZED partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 Using where
4 DEPENDENT SUBQUERY lineitem ref i_l_shipdate,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey i_l_suppkey_partkey 10 dbt3_s001.partsupp.ps_partkey,dbt3_s001.partsupp.ps_suppkey 8 100.00 Using where
Warnings:
Note 1276 Field or reference 'dbt3_s001.partsupp.ps_partkey' of SELECT #4 was resolved in SELECT #2
Note 1276 Field or reference 'dbt3_s001.partsupp.ps_suppkey' of SELECT #4 was resolved in SELECT #2
Note 1003 select sql_calc_found_rows `dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`supplier`.`s_address` AS `s_address` from `dbt3_s001`.`supplier` semi join (`dbt3_s001`.`part` join `dbt3_s001`.`partsupp`) join `dbt3_s001`.`nation` where ((`dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey`) and (`dbt3_s001`.`nation`.`n_name` = 'UNITED STATES') and (`dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey`) and (`dbt3_s001`.`partsupp`.`ps_availqty` > <expr_cache><`dbt3_s001`.`partsupp`.`ps_partkey`,`dbt3_s001`.`partsupp`.`ps_suppkey`>((select (0.5 * sum(`dbt3_s001`.`lineitem`.`l_quantity`)) from `dbt3_s001`.`lineitem` where ((`dbt3_s001`.`lineitem`.`l_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey`) and (`dbt3_s001`.`lineitem`.`l_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey`) and (`dbt3_s001`.`lineitem`.`l_shipDATE` >= <cache>(cast('1993-01-01' as date))) and (`dbt3_s001`.`lineitem`.`l_shipDATE` < <cache>((cast('1993-01-01' as date) + interval '1' year))))))) and (`dbt3_s001`.`part`.`p_name` like 'g%')) order by `dbt3_s001`.`supplier`.`s_name` limit 10
select sql_calc_found_rows
s_name, s_address
from supplier, nation
where s_suppkey in (select ps_suppkey from partsupp
where ps_partkey in (select p_partkey from part
where p_name like 'g%')
and ps_availqty >
(select 0.5 * sum(l_quantity)
from lineitem
where l_partkey = ps_partkey
and l_suppkey = ps_suppkey
and l_shipdate >= date('1993-01-01')
and l_shipdate < date('1993-01-01') +
interval '1' year ))
and s_nationkey = n_nationkey
and n_name = 'UNITED STATES'
order by s_name
limit 10;
s_name s_address
Supplier#000000010 Saygah3gYWMp72i PY
set optimizer_use_condition_selectivity=3;
EXPLAIN EXTENDED select sql_calc_found_rows
s_name, s_address
from supplier, nation
where s_suppkey in (select ps_suppkey from partsupp
where ps_partkey in (select p_partkey from part
where p_name like 'g%')
and ps_availqty >
(select 0.5 * sum(l_quantity)
from lineitem
where l_partkey = ps_partkey
and l_suppkey = ps_suppkey
and l_shipdate >= date('1993-01-01')
and l_shipdate < date('1993-01-01') +
interval '1' year ))
and s_nationkey = n_nationkey
and n_name = 'UNITED STATES'
order by s_name
limit 10;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY nation ALL PRIMARY NULL NULL NULL 25 4.00 Using where; Using temporary; Using filesort
1 PRIMARY supplier ref PRIMARY,i_s_nationkey i_s_nationkey 5 dbt3_s001.nation.n_nationkey 1 100.00
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
2 MATERIALIZED part ALL PRIMARY NULL NULL NULL 200 4.17 Using where
2 MATERIALIZED partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 Using where
4 DEPENDENT SUBQUERY lineitem ref i_l_shipdate,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey i_l_suppkey_partkey 10 dbt3_s001.partsupp.ps_partkey,dbt3_s001.partsupp.ps_suppkey 8 100.00 Using where
Warnings:
Note 1276 Field or reference 'dbt3_s001.partsupp.ps_partkey' of SELECT #4 was resolved in SELECT #2
Note 1276 Field or reference 'dbt3_s001.partsupp.ps_suppkey' of SELECT #4 was resolved in SELECT #2
Note 1003 select sql_calc_found_rows `dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`supplier`.`s_address` AS `s_address` from `dbt3_s001`.`supplier` semi join (`dbt3_s001`.`part` join `dbt3_s001`.`partsupp`) join `dbt3_s001`.`nation` where ((`dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey`) and (`dbt3_s001`.`nation`.`n_name` = 'UNITED STATES') and (`dbt3_s001`.`supplier`.`s_nationkey` = `dbt3_s001`.`nation`.`n_nationkey`) and (`dbt3_s001`.`partsupp`.`ps_availqty` > <expr_cache><`dbt3_s001`.`partsupp`.`ps_partkey`,`dbt3_s001`.`partsupp`.`ps_suppkey`>((select (0.5 * sum(`dbt3_s001`.`lineitem`.`l_quantity`)) from `dbt3_s001`.`lineitem` where ((`dbt3_s001`.`lineitem`.`l_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey`) and (`dbt3_s001`.`lineitem`.`l_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey`) and (`dbt3_s001`.`lineitem`.`l_shipDATE` >= <cache>(cast('1993-01-01' as date))) and (`dbt3_s001`.`lineitem`.`l_shipDATE` < <cache>((cast('1993-01-01' as date) + interval '1' year))))))) and (`dbt3_s001`.`part`.`p_name` like 'g%')) order by `dbt3_s001`.`supplier`.`s_name` limit 10
select sql_calc_found_rows
s_name, s_address
from supplier, nation
where s_suppkey in (select ps_suppkey from partsupp
where ps_partkey in (select p_partkey from part
where p_name like 'g%')
and ps_availqty >
(select 0.5 * sum(l_quantity)
from lineitem
where l_partkey = ps_partkey
and l_suppkey = ps_suppkey
and l_shipdate >= date('1993-01-01')
and l_shipdate < date('1993-01-01') +
interval '1' year ))
and s_nationkey = n_nationkey
and n_name = 'UNITED STATES'
order by s_name
limit 10;
s_name s_address
Supplier#000000010 Saygah3gYWMp72i PY
DROP DATABASE dbt3_s001;
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
set use_stat_tables=@save_use_stat_tables;
set optimizer_switch=@save_optimizer_switch_for_selectivity_test;
SET SESSION STORAGE_ENGINE=DEFAULT;
SET @start_global_value = @@global.optimizer_use_condition_selectivity;
SELECT @start_global_value;
@start_global_value
1
SET @start_session_value = @@session.optimizer_use_condition_selectivity;
SELECT @start_session_value;
@start_session_value
1
'#--------------------FN_DYNVARS_115_01-------------------------#'
SET @@global.optimizer_use_condition_selectivity = DEFAULT;
SELECT @@global.optimizer_use_condition_selectivity;
@@global.optimizer_use_condition_selectivity
1
SET @@session.optimizer_use_condition_selectivity = DEFAULT;
SELECT @@session.optimizer_use_condition_selectivity;
@@session.optimizer_use_condition_selectivity
1
'#--------------------FN_DYNVARS_115_02-------------------------#'
SET @@global.optimizer_use_condition_selectivity = DEFAULT;
SELECT @@global.optimizer_use_condition_selectivity = 1;
@@global.optimizer_use_condition_selectivity = 1
1
SET @@session.optimizer_use_condition_selectivity = DEFAULT;
SELECT @@session.optimizer_use_condition_selectivity = 1;
@@session.optimizer_use_condition_selectivity = 1
1
'#--------------------FN_DYNVARS_115_03-------------------------#'
SELECT @@global.optimizer_use_condition_selectivity;
@@global.optimizer_use_condition_selectivity
1
SET @@global.optimizer_use_condition_selectivity = 1;
SELECT @@global.optimizer_use_condition_selectivity;
@@global.optimizer_use_condition_selectivity
1
SET @@global.optimizer_use_condition_selectivity = 2;
SELECT @@global.optimizer_use_condition_selectivity;
@@global.optimizer_use_condition_selectivity
2
SET @@global.optimizer_use_condition_selectivity = 3;
SELECT @@global.optimizer_use_condition_selectivity;
@@global.optimizer_use_condition_selectivity
3
'#--------------------FN_DYNVARS_115_04-------------------------#'
SELECT @@session.optimizer_use_condition_selectivity;
@@session.optimizer_use_condition_selectivity
1
SET @@session.optimizer_use_condition_selectivity = 1;
SELECT @@session.optimizer_use_condition_selectivity;
@@session.optimizer_use_condition_selectivity
1
SET @@session.optimizer_use_condition_selectivity = 2;
SELECT @@session.optimizer_use_condition_selectivity;
@@session.optimizer_use_condition_selectivity
2
SET @@session.optimizer_use_condition_selectivity = 3;
SELECT @@session.optimizer_use_condition_selectivity;
@@session.optimizer_use_condition_selectivity
3
'#------------------FN_DYNVARS_115_05-----------------------#'
SET @@global.optimizer_use_condition_selectivity = ON;
ERROR 42000: Incorrect argument type to variable 'optimizer_use_condition_selectivity'
SET @@global.optimizer_use_condition_selectivity = OFF;
ERROR 42000: Incorrect argument type to variable 'optimizer_use_condition_selectivity'
SET @@session.optimizer_use_condition_selectivity = 65530.34;
ERROR 42000: Incorrect argument type to variable 'optimizer_use_condition_selectivity'
SET @@session.optimizer_use_condition_selectivity = test;
ERROR 42000: Incorrect argument type to variable 'optimizer_use_condition_selectivity'
'#------------------FN_DYNVARS_115_06-----------------------#'
SELECT @@global.optimizer_use_condition_selectivity = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME='optimizer_use_condition_selectivity';
@@global.optimizer_use_condition_selectivity = VARIABLE_VALUE
1
'#------------------FN_DYNVARS_115_07-----------------------#'
SELECT @@session.optimizer_use_condition_selectivity = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.SESSION_VARIABLES
WHERE VARIABLE_NAME='optimizer_use_condition_selectivity';
@@session.optimizer_use_condition_selectivity = VARIABLE_VALUE
1
'#---------------------FN_DYNVARS_115_08----------------------#'
SET @@optimizer_use_condition_selectivity = 1;
SET @@global.optimizer_use_condition_selectivity = 3;
SELECT @@optimizer_use_condition_selectivity = @@global.optimizer_use_condition_selectivity;
@@optimizer_use_condition_selectivity = @@global.optimizer_use_condition_selectivity
0
'#---------------------FN_DYNVARS_115_09----------------------#'
SET @@optimizer_use_condition_selectivity = 2;
SELECT @@optimizer_use_condition_selectivity = @@local.optimizer_use_condition_selectivity;
@@optimizer_use_condition_selectivity = @@local.optimizer_use_condition_selectivity
1
SELECT @@local.optimizer_use_condition_selectivity = @@session.optimizer_use_condition_selectivity;
@@local.optimizer_use_condition_selectivity = @@session.optimizer_use_condition_selectivity
1
SET @@global.optimizer_use_condition_selectivity = @start_global_value;
SELECT @@global.optimizer_use_condition_selectivity;
@@global.optimizer_use_condition_selectivity
1
SET @@session.optimizer_use_condition_selectivity = @start_session_value;
SELECT @@session.optimizer_use_condition_selectivity;
@@session.optimizer_use_condition_selectivity
1
--source include/load_sysvars.inc
#################################################################
# START OF optimizer_use_condition_selectivity TESTS #
#################################################################
#############################################################
# Save initial value #
#############################################################
SET @start_global_value = @@global.optimizer_use_condition_selectivity;
SELECT @start_global_value;
SET @start_session_value = @@session.optimizer_use_condition_selectivity;
SELECT @start_session_value;
--echo '#--------------------FN_DYNVARS_115_01-------------------------#'
#########################################################################
# Display the DEFAULT value of optimizer_use_condition_selectivity #
#########################################################################
SET @@global.optimizer_use_condition_selectivity = DEFAULT;
SELECT @@global.optimizer_use_condition_selectivity;
SET @@session.optimizer_use_condition_selectivity = DEFAULT;
SELECT @@session.optimizer_use_condition_selectivity;
--echo '#--------------------FN_DYNVARS_115_02-------------------------#'
#########################################################################
# Check the DEFAULT value of optimizer_use_condition_selectivity #
#########################################################################
SET @@global.optimizer_use_condition_selectivity = DEFAULT;
SELECT @@global.optimizer_use_condition_selectivity = 1;
SET @@session.optimizer_use_condition_selectivity = DEFAULT;
SELECT @@session.optimizer_use_condition_selectivity = 1;
--echo '#--------------------FN_DYNVARS_115_03-------------------------#'
#############################################################################################
# Change the value of optimizer_use_condition_selectivity to a valid value for GLOBAL Scope #
#############################################################################################
SELECT @@global.optimizer_use_condition_selectivity;
SET @@global.optimizer_use_condition_selectivity = 1;
SELECT @@global.optimizer_use_condition_selectivity;
SET @@global.optimizer_use_condition_selectivity = 2;
SELECT @@global.optimizer_use_condition_selectivity;
SET @@global.optimizer_use_condition_selectivity = 3;
SELECT @@global.optimizer_use_condition_selectivity;
--echo '#--------------------FN_DYNVARS_115_04-------------------------#'
#############################################################################################
# Change the value of optimizer_use_condition_selectivity to a valid value for SESSION Scope#
#############################################################################################
SELECT @@session.optimizer_use_condition_selectivity;
SET @@session.optimizer_use_condition_selectivity = 1;
SELECT @@session.optimizer_use_condition_selectivity;
SET @@session.optimizer_use_condition_selectivity = 2;
SELECT @@session.optimizer_use_condition_selectivity;
SET @@session.optimizer_use_condition_selectivity = 3;
SELECT @@session.optimizer_use_condition_selectivity;
--echo '#------------------FN_DYNVARS_115_05-----------------------#'
###############################################################################
# Change the value of optimizer_use_condition_selectivity to an invalid value #
##############################################################################
--Error ER_WRONG_TYPE_FOR_VAR
SET @@global.optimizer_use_condition_selectivity = ON;
--Error ER_WRONG_TYPE_FOR_VAR
SET @@global.optimizer_use_condition_selectivity = OFF;
--Error ER_WRONG_TYPE_FOR_VAR
SET @@session.optimizer_use_condition_selectivity = 65530.34;
--Error ER_WRONG_TYPE_FOR_VAR
SET @@session.optimizer_use_condition_selectivity = test;
--echo '#------------------FN_DYNVARS_115_06-----------------------#'
####################################################################
# Check if the value in GLOBAL Table matches value in variable #
####################################################################
SELECT @@global.optimizer_use_condition_selectivity = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME='optimizer_use_condition_selectivity';
--echo '#------------------FN_DYNVARS_115_07-----------------------#'
####################################################################
# Check if the value in SESSION Table matches value in variable #
####################################################################
SELECT @@session.optimizer_use_condition_selectivity = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.SESSION_VARIABLES
WHERE VARIABLE_NAME='optimizer_use_condition_selectivity';
--echo '#---------------------FN_DYNVARS_115_08----------------------#'
###############################################################################
# Check if global and session variable are independent of each other #
###############################################################################
SET @@optimizer_use_condition_selectivity = 1;
SET @@global.optimizer_use_condition_selectivity = 3;
SELECT @@optimizer_use_condition_selectivity = @@global.optimizer_use_condition_selectivity;
--echo '#---------------------FN_DYNVARS_115_09----------------------#'
###############################################################################
# Check if accessing variable with SESSION,LOCAL and without SCOPE points #
# to same session variable #
###############################################################################
SET @@optimizer_use_condition_selectivity = 2;
SELECT @@optimizer_use_condition_selectivity = @@local.optimizer_use_condition_selectivity;
SELECT @@local.optimizer_use_condition_selectivity = @@session.optimizer_use_condition_selectivity;
####################################
# Restore initial value #
####################################
SET @@global.optimizer_use_condition_selectivity = @start_global_value;
SELECT @@global.optimizer_use_condition_selectivity;
SET @@session.optimizer_use_condition_selectivity = @start_session_value;
SELECT @@session.optimizer_use_condition_selectivity;
########################################################################
# END OF optimizer_use_condition_selectivity TESTS #
########################################################################
--source include/have_stat_tables.inc
select @@global.use_stat_tables;
select @@session.use_stat_tables;
set @save_use_stat_tables=@@use_stat_tables;
set use_stat_tables='preferably';
--disable_warnings
DROP DATABASE IF EXISTS dbt3_s001;
--enable_warnings
CREATE DATABASE dbt3_s001;
use dbt3_s001;
set @save_optimizer_use_condition_selectivity=@@optimizer_use_condition_selectivity;
--disable_query_log
--disable_result_log
--disable_warnings
--source include/dbt3_s001.inc
ANALYZE TABLE
customer, lineitem, nation, orders, part, partsupp, region, supplier;
FLUSH TABLE
customer, lineitem, nation, orders, part, partsupp, region, supplier;
--enable_warnings
--enable_result_log
--enable_query_log
let $Q20=
select sql_calc_found_rows
s_name, s_address
from supplier, nation
where s_suppkey in (select ps_suppkey from partsupp
where ps_partkey in (select p_partkey from part
where p_name like 'g%')
and ps_availqty >
(select 0.5 * sum(l_quantity)
from lineitem
where l_partkey = ps_partkey
and l_suppkey = ps_suppkey
and l_shipdate >= date('1993-01-01')
and l_shipdate < date('1993-01-01') +
interval '1' year ))
and s_nationkey = n_nationkey
and n_name = 'UNITED STATES'
order by s_name
limit 10;
eval EXPLAIN EXTENDED $Q20;
eval $Q20;
set optimizer_use_condition_selectivity=3;
eval EXPLAIN EXTENDED $Q20;
eval $Q20;
DROP DATABASE dbt3_s001;
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
set use_stat_tables=@save_use_stat_tables;
--source include/have_innodb.inc
SET SESSION STORAGE_ENGINE='InnoDB';
set @save_optimizer_switch_for_selectivity_test=@@optimizer_switch;
set optimizer_switch='extended_keys=on';
--source selectivity.test
set optimizer_switch=@save_optimizer_switch_for_selectivity_test;
SET SESSION STORAGE_ENGINE=DEFAULT;
......@@ -1273,6 +1273,20 @@ out_of_range:
return 1;
}
double Field_num::middle_point_pos(Field *min, Field *max)
{
double n, d;
n= val_real() - min->val_real();
if (n < 0)
return 0.0;
d= max->val_real() - min->val_real();
if (d <= 0)
return 1.0;
return min(n/d, 1.0);
}
/**
Process decimal library return codes and issue warnings for overflow and
truncation.
......@@ -1344,6 +1358,8 @@ Field::Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
comment.length=0;
field_index= 0;
is_stat_field= FALSE;
cond_selectivity= 1.0;
next_equal_field= NULL;
}
......@@ -6167,6 +6183,46 @@ int Field_str::store(double nr)
return store(buff, length, &my_charset_numeric);
}
static
inline ulonglong char_prefix_to_ulonglong(uchar *src)
{
uint sz= sizeof(ulonglong);
for (uint i= 0; i < sz/2; i++)
{
uchar tmp= src[i];
src[i]= src[sz-1-i];
src[sz-1-i]= tmp;
}
return uint8korr(src);
}
double Field_str::middle_point_pos(Field *min, Field *max)
{
uchar mp_prefix[sizeof(ulonglong)];
uchar minp_prefix[sizeof(ulonglong)];
uchar maxp_prefix[sizeof(ulonglong)];
ulonglong mp, minp, maxp;
my_strnxfrm(charset(), mp_prefix, sizeof(mp),
ptr + length_size(), sizeof(mp) * charset()->mbmaxlen);
my_strnxfrm(charset(), minp_prefix, sizeof(minp),
min->ptr + length_size(),
sizeof(minp) * charset()->mbmaxlen);
my_strnxfrm(charset(), maxp_prefix, sizeof(maxp),
max->ptr + length_size(),
sizeof(maxp) * charset()->mbmaxlen);
mp= char_prefix_to_ulonglong(mp_prefix);
minp= char_prefix_to_ulonglong(minp_prefix);
maxp= char_prefix_to_ulonglong(maxp_prefix);
double n, d;
n= mp - minp;
if (n < 0)
return 0.0;
d= maxp - minp;
if (d <= 0)
return 1.0;
return min(n/d, 1.0);
}
uint Field::is_equal(Create_field *new_field)
{
......
......@@ -220,7 +220,23 @@ public:
*/
bool is_created_from_null_item;
bool is_stat_field; /* TRUE in Field objects created for column min/max values */
/* TRUE in Field objects created for column min/max values */
bool is_stat_field;
/*
Selectivity of the range condition over this field.
When calculating this selectivity a range predicate
is taken into account only if:
- it is extracted from the WHERE clause
- it depends only on the table the field belongs to
*/
double cond_selectivity;
/*
The next field in the class of equal fields at the top AND level
of the WHERE clause
*/
Field *next_equal_field;
/*
This structure is used for statistical data on the column
......@@ -703,6 +719,11 @@ public:
virtual bool hash_join_is_possible() { return TRUE; }
virtual bool eq_cmp_as_binary() { return TRUE; }
virtual double middle_point_pos(Field *min, Field *max)
{
return (double) 1.0;
}
friend int cre_myisam(char * name, register TABLE *form, uint options,
ulonglong auto_increment_value);
friend class Copy_field;
......@@ -821,6 +842,7 @@ public:
bool get_int(CHARSET_INFO *cs, const char *from, uint len,
longlong *rnd, ulonglong unsigned_max,
longlong signed_min, longlong signed_max);
double middle_point_pos(Field *min, Field *max);
};
......@@ -866,6 +888,8 @@ public:
virtual bool str_needs_quotes() { return TRUE; }
uint is_equal(Create_field *new_field);
bool eq_cmp_as_binary() { return test(flags & BINARY_FLAG); }
virtual uint length_size() { return 0; }
double middle_point_pos(Field *min, Field *max);
};
/* base class for Field_string, Field_varstring and Field_blob */
......@@ -1894,6 +1918,7 @@ public:
uint new_null_bit);
uint is_equal(Create_field *new_field);
void hash(ulong *nr, ulong *nr2);
uint length_size() { return length_bytes; }
private:
int do_save_field_metadata(uchar *first_byte);
};
......
......@@ -5567,7 +5567,8 @@ Item *Item_bool_rowready_func2::negated_item()
*/
Item_equal::Item_equal(Item *f1, Item *f2, bool with_const_item)
: Item_bool_func(), eval_item(0), cond_false(0), context_field(NULL)
: Item_bool_func(), eval_item(0), cond_false(0), context_field(NULL),
link_equal_fields(FALSE)
{
const_item_cache= 0;
with_const= with_const_item;
......@@ -5590,7 +5591,8 @@ Item_equal::Item_equal(Item *f1, Item *f2, bool with_const_item)
*/
Item_equal::Item_equal(Item_equal *item_equal)
: Item_bool_func(), eval_item(0), cond_false(0), context_field(NULL)
: Item_bool_func(), eval_item(0), cond_false(0), context_field(NULL),
link_equal_fields(FALSE)
{
const_item_cache= 0;
List_iterator_fast<Item> li(item_equal->equal_items);
......@@ -5833,6 +5835,9 @@ bool Item_equal::fix_fields(THD *thd, Item **ref)
DBUG_ASSERT(fixed == 0);
Item_equal_fields_iterator it(*this);
Item *item;
Field *first_equal_field;
Field *last_equal_field;
Field *prev_equal_field= NULL;
not_null_tables_cache= used_tables_cache= 0;
const_item_cache= 0;
while ((item= it++))
......@@ -5846,7 +5851,18 @@ bool Item_equal::fix_fields(THD *thd, Item **ref)
maybe_null= 1;
if (!item->get_item_equal())
item->set_item_equal(this);
if (link_equal_fields && item->real_item()->type() == FIELD_ITEM)
{
last_equal_field= ((Item_field *) (item->real_item()))->field;
if (!prev_equal_field)
first_equal_field= last_equal_field;
else
prev_equal_field->next_equal_field= last_equal_field;
prev_equal_field= last_equal_field;
}
}
if (prev_equal_field && last_equal_field != first_equal_field)
last_equal_field->next_equal_field= first_equal_field;
fix_length_and_dec();
fixed= 1;
return FALSE;
......
......@@ -1730,6 +1730,7 @@ class Item_equal: public Item_bool_func
used in the original equality.
*/
Item_field *context_field;
bool link_equal_fields;
public:
inline Item_equal()
: Item_bool_func(), with_const(FALSE), eval_item(0), cond_false(0),
......@@ -1762,6 +1763,7 @@ public:
CHARSET_INFO *compare_collation();
void set_context_field(Item_field *ctx_field) { context_field= ctx_field; }
void set_link_equal_fields(bool flag) { link_equal_fields= flag; }
friend class Item_equal_fields_iterator;
friend Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
Item_equal *item_equal);
......
......@@ -117,6 +117,7 @@
#include "records.h" // init_read_record, end_read_record
#include <m_ctype.h>
#include "sql_select.h"
#include "sql_statistics.h"
#include "filesort.h" // filesort_free_buffers
#ifndef EXTRA_DEBUG
......@@ -3211,6 +3212,224 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
DBUG_RETURN(records ? test(quick) : -1);
}
/****************************************************************************
* Condition selectivity module
****************************************************************************/
static
bool create_key_parts_for_pseudo_indexes(RANGE_OPT_PARAM *param,
MY_BITMAP *used_fields)
{
Field **field_ptr;
TABLE *table= param->table;
uint parts= 0;
for (field_ptr= table->field; *field_ptr; field_ptr++)
{
if (bitmap_is_set(used_fields, (*field_ptr)->field_index))
parts++;
}
KEY_PART *key_part;
uint keys= 0;
if (!(key_part= (KEY_PART *) alloc_root(param->mem_root,
sizeof(KEY_PART) * parts)))
return TRUE;
param->key_parts= key_part;
for (field_ptr= table->field; *field_ptr; field_ptr++)
{
if (bitmap_is_set(used_fields, (*field_ptr)->field_index))
{
Field *field= *field_ptr;
uint16 store_length;
key_part->key= keys;
key_part->part= 0;
key_part->length= (uint16) field->key_length();
store_length= key_part->length;
if (field->real_maybe_null())
store_length+= HA_KEY_NULL_LENGTH;
if (field->real_type() == MYSQL_TYPE_VARCHAR)
store_length+= HA_KEY_BLOB_LENGTH;
key_part->store_length= store_length;
key_part->field= field;
key_part->image_type= Field::itRAW;
param->key[keys]= key_part;
keys++;
key_part++;
}
}
param->keys= keys;
param->key_parts_end= key_part;
return FALSE;
}
static
double records_in_column_ranges(PARAM *param, uint idx,
SEL_ARG *tree)
{
SEL_ARG_RANGE_SEQ seq;
KEY_MULTI_RANGE range;
range_seq_t seq_it;
double rows;
Field *field;
uint flags= 0;
double total_rows= 0;
RANGE_SEQ_IF seq_if = {NULL, sel_arg_range_seq_init,
sel_arg_range_seq_next, 0, 0};
/* Handle cases when we don't have a valid non-empty list of range */
if (!tree)
return HA_POS_ERROR;
if (tree->type == SEL_ARG::IMPOSSIBLE)
return (0L);
field= tree->field;
seq.keyno= idx;
seq.real_keyno= MAX_KEY;
seq.param= param;
seq.start= tree;
seq_it= seq_if.init((void *) &seq, 0, flags);
while (!seq_if.next(seq_it, &range))
{
key_range *min_endp, *max_endp;
min_endp= range.start_key.length? &range.start_key : NULL;
max_endp= range.end_key.length? &range.end_key : NULL;
rows= get_column_range_cardinality(field, min_endp, max_endp);
if (HA_POS_ERROR == rows)
{
total_rows= HA_POS_ERROR;
break;
}
total_rows += rows;
}
return total_rows;
}
bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item *cond)
{
uint keynr;
uint max_quick_key_parts= 0;
MY_BITMAP *used_fields= &table->cond_set;
double table_records= table->stat_records();
DBUG_ENTER("calculate_cond_selectivity_for_table");
table->cond_selectivity= 1.0;
if (bitmap_is_clear_all(used_fields))
DBUG_RETURN(FALSE);
PARAM param;
MEM_ROOT alloc;
init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0,
MYF(MY_THREAD_SPECIFIC));
param.thd= thd;
param.mem_root= &alloc;
param.old_root= thd->mem_root;
param.table= table;
param.is_ror_scan= FALSE;
if (create_key_parts_for_pseudo_indexes(&param, used_fields))
{
free_root(&alloc, MYF(0));
DBUG_RETURN(FALSE);
}
param.prev_tables= param.read_tables= 0;
param.current_table= table->map;
param.using_real_indexes= FALSE;
param.real_keynr[0]= 0;
param.alloced_sel_args= 0;
thd->no_errors=1; // Don't warn about NULL
SEL_TREE *tree;
SEL_ARG **key, **end;
uint idx= 0;
tree= get_mm_tree(&param, cond);
if (!tree)
goto end;
for (key= tree->keys, end= key + param.keys; key != end; key++, idx++)
{
double rows;
if (*key)
{
rows= records_in_column_ranges(&param, idx, *key);
if (rows != HA_POS_ERROR)
(*key)->field->cond_selectivity= rows/table_records;
}
}
for (Field **field_ptr= table->field; *field_ptr; field_ptr++)
{
Field *table_field= *field_ptr;
if (bitmap_is_set(table->read_set, table_field->field_index) &&
table_field->cond_selectivity < 1.0)
table->cond_selectivity*= table_field->cond_selectivity;
}
/* Calculate the selectivity of the range conditions supported by indexes */
bitmap_clear_all(used_fields);
for (keynr= 0; keynr < table->s->keys; keynr++)
{
if (table->quick_keys.is_set(keynr))
set_if_bigger(max_quick_key_parts, table->quick_key_parts[keynr]);
}
for (uint quick_key_parts= max_quick_key_parts;
quick_key_parts; quick_key_parts--)
{
for (keynr= 0; keynr < table->s->keys; keynr++)
{
if (table->quick_keys.is_set(keynr) &&
table->quick_key_parts[keynr] == quick_key_parts)
{
uint i;
uint used_key_parts= table->quick_key_parts[keynr];
double quick_cond_selectivity= table->quick_rows[keynr] /
table_records;
KEY *key_info= table->key_info + keynr;
KEY_PART_INFO* key_part= key_info->key_part;
for (i= 0; i < used_key_parts; i++, key_part++)
{
if (bitmap_is_set(used_fields, key_part->fieldnr-1))
break;
bitmap_set_bit(used_fields, key_part->fieldnr-1);
}
if (i)
{
double f1= key_info->actual_rec_per_key(i-1);
double f2= key_info->actual_rec_per_key(i);
table->cond_selectivity*= quick_cond_selectivity * f1 / f2;
}
}
}
}
end:
thd->mem_root= param.old_root;
free_root(&alloc, MYF(0));
DBUG_RETURN(FALSE);
}
/****************************************************************************
* Condition selectivity code ends
****************************************************************************/
/****************************************************************************
* Partition pruning module
****************************************************************************/
......
......@@ -1042,6 +1042,8 @@ SQL_SELECT *make_select(TABLE *head, table_map const_tables,
table_map read_tables, COND *conds,
bool allow_null_cond, int *error);
bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item *cond);
#ifdef WITH_PARTITION_STORAGE_ENGINE
bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond);
void store_key_image_to_rec(Field *field, uchar *ptr, uint len);
......
......@@ -268,8 +268,10 @@ walk_up_n_right:
range->end_key.keypart_map= make_prev_keypart_map(cur->max_key_parts);
if (!(cur->min_key_flag & ~NULL_RANGE) && !cur->max_key_flag &&
(uint)key_tree->part+1 == seq->param->table->key_info[seq->real_keyno].key_parts &&
(seq->param->table->key_info[seq->real_keyno].flags & HA_NOSAME) &&
(seq->real_keyno == MAX_KEY ||
((uint)key_tree->part+1 ==
seq->param->table->key_info[seq->real_keyno].key_parts &&
(seq->param->table->key_info[seq->real_keyno].flags & HA_NOSAME))) &&
range->start_key.length == range->end_key.length &&
!memcmp(seq->param->min_key,seq->param->max_key,range->start_key.length))
range->range_flag= UNIQUE_RANGE | (cur->min_key_flag & NULL_RANGE);
......
......@@ -3889,7 +3889,7 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd)
&tmpname, (uint) strlen(path)+1,
&group_buff, (!using_unique_constraint ?
uniq_tuple_length_arg : 0),
&bitmaps, bitmap_buffer_size(1)*3,
&bitmaps, bitmap_buffer_size(1)*5,
NullS))
{
if (temp_pool_slot != MY_BIT_NONE)
......
......@@ -283,6 +283,7 @@ public:
{
pos->records_read= best_loose_scan_records;
pos->key= best_loose_scan_start_key;
pos->cond_selectivity= 1.0;
pos->loosescan_picker.loosescan_key= best_loose_scan_key;
pos->loosescan_picker.loosescan_parts= best_max_loose_keypart + 1;
pos->use_join_buffer= FALSE;
......
......@@ -499,6 +499,7 @@ typedef struct system_variables
ulong net_write_timeout;
ulong optimizer_prune_level;
ulong optimizer_search_depth;
ulong optimizer_use_condition_selectivity;
ulong use_stat_tables;
ulong preload_buff_size;
ulong profiling_history_size;
......
......@@ -228,6 +228,7 @@ template <class T> bool valid_buffer_range(T jump,
#define OPTIMIZER_SWITCH_TABLE_ELIMINATION (1ULL << 26)
#define OPTIMIZER_SWITCH_EXTENDED_KEYS (1ULL << 27)
#define OPTIMIZER_SWITCH_EXISTS_TO_IN (1ULL << 28)
#define OPTIMIZER_SWITCH_USE_CONDITION_SELECTIVITY (1ULL << 29)
#define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
......
This diff is collapsed.
......@@ -292,6 +292,8 @@ typedef struct st_join_table {
/* psergey-todo: make the below have type double, like POSITION::records_read? */
ha_rows records_read;
double cond_selectivity;
/* Startup cost for execution */
double startup_cost;
......@@ -762,6 +764,8 @@ typedef struct st_position :public Sql_alloc
*/
double records_read;
double cond_selectivity;
/*
Cost accessing the table in course of the entire complete join execution,
i.e. cost of one access method use (e.g. 'range' or 'ref' scan ) times
......@@ -1804,6 +1808,8 @@ void eliminate_tables(JOIN *join);
/* Index Condition Pushdown entry point function */
void push_index_cond(JOIN_TAB *tab, uint keyno);
#define OPT_LINK_EQUAL_FIELDS 1
/****************************************************************************
Temporary table support for SQL Runtime
***************************************************************************/
......
......@@ -26,6 +26,7 @@
#include "sql_base.h"
#include "key.h"
#include "sql_statistics.h"
#include "opt_range.h"
#include "my_atomic.h"
/*
......@@ -3054,3 +3055,51 @@ void set_statistics_for_table(THD *thd, TABLE *table)
key_info->read_stats->get_avg_frequency(0) > 0.5);
}
}
double get_column_avg_frequency(Field * field)
{
double res;
TABLE *table= field->table;
Column_statistics *col_stats= table->s->field[field->field_index]->read_stats;
if (!col_stats)
res= table->stat_records();
else
res= col_stats->get_avg_frequency();
return res;
}
double get_column_range_cardinality(Field *field,
key_range *min_endp,
key_range *max_endp)
{
double res;
TABLE *table= field->table;
Column_statistics *col_stats= table->field[field->field_index]->read_stats;
if (!col_stats)
res= table->stat_records();
else if (min_endp->length == max_endp->length &&
!memcmp(min_endp->key, max_endp->key, min_endp->length))
{
res= col_stats->get_avg_frequency();
}
else
{
if (col_stats->min_value && col_stats->max_value)
{
store_key_image_to_rec(field, (uchar *) min_endp->key, min_endp->length);
double min_mp_pos= field->middle_point_pos(col_stats->min_value,
col_stats->max_value);
store_key_image_to_rec(field, (uchar *) max_endp->key, max_endp->length);
double max_mp_pos= field->middle_point_pos(col_stats->min_value,
col_stats->max_value);
res= table->stat_records() * (max_mp_pos - min_mp_pos);
}
else
res= table->stat_records();
}
return res;
}
......@@ -90,6 +90,12 @@ int rename_column_in_stat_tables(THD *thd, TABLE *tab, Field *col,
const char *new_name);
void set_statistics_for_table(THD *thd, TABLE *table);
double get_column_avg_frequency(Field * field);
double get_column_range_cardinality(Field *field,
key_range *min_endp,
key_range *max_endp);
class Columns_statistics;
class Index_statistics;
......
......@@ -1424,6 +1424,22 @@ static Sys_var_ulong Sys_optimizer_prune_level(
SESSION_VAR(optimizer_prune_level), CMD_LINE(REQUIRED_ARG),
VALID_RANGE(0, 1), DEFAULT(1), BLOCK_SIZE(1));
static Sys_var_ulong Sys_optimizer_use_condition_selectivity(
"optimizer_use_condition_selectivity",
"Controls selectivity of which conditions the optimizer takes into "
"account to calculate cardinality of a partial join when it searches "
"for the best execution plan "
"Meaning: "
"1 - use selectivity of index backed range conditions to calculate "
"cardinality of the partial join if the last joined table is "
"accessed by full table scan or an index scan "
"2 - use selectivity of index backed range conditions to calculate "
"cardinality of the partial join in any case "
"3 - additionally always use selectivity of range conditions that are "
"not backed by any index to calculate cardinality of the partial join",
SESSION_VAR(optimizer_use_condition_selectivity), CMD_LINE(REQUIRED_ARG),
VALID_RANGE(1, 3), DEFAULT(1), BLOCK_SIZE(1));
/** Warns about deprecated value 63 */
static bool fix_optimizer_search_depth(sys_var *self, THD *thd,
enum_var_type type)
......
......@@ -2630,7 +2630,7 @@ partititon_err:
/* Allocate bitmaps */
bitmap_size= share->column_bitmap_size;
if (!(bitmaps= (uchar*) alloc_root(&outparam->mem_root, bitmap_size*5)))
if (!(bitmaps= (uchar*) alloc_root(&outparam->mem_root, bitmap_size*6)))
goto err;
bitmap_init(&outparam->def_read_set,
(my_bitmap_map*) bitmaps, share->fields, FALSE);
......@@ -2642,8 +2642,12 @@ partititon_err:
(my_bitmap_map*) (bitmaps+bitmap_size*3), share->fields, FALSE);
bitmap_init(&outparam->eq_join_set,
(my_bitmap_map*) (bitmaps+bitmap_size*4), share->fields, FALSE);
bitmap_init(&outparam->cond_set,
(my_bitmap_map*) (bitmaps+bitmap_size*5), share->fields, FALSE);
outparam->default_column_bitmaps();
outparam->cond_selectivity= 1.0;
/* The table struct is now initialized; Open the table */
error= 2;
if (db_stat)
......
......@@ -1026,6 +1026,7 @@ public:
my_bitmap_map *bitmap_init_value;
MY_BITMAP def_read_set, def_write_set, def_vcol_set, tmp_set;
MY_BITMAP eq_join_set; /* used to mark equi-joined fields */
MY_BITMAP cond_set; /* used to mark fields from sargable conditions*/
MY_BITMAP *read_set, *write_set, *vcol_set; /* Active column sets */
/*
The ID of the query that opened and is using this table. Has different
......@@ -1078,6 +1079,8 @@ public:
*/
ha_rows quick_condition_rows;
double cond_selectivity;
table_map map; /* ID bit of table (1,2,4,8,16...) */
uint lock_position; /* Position in MYSQL_LOCK.table */
......
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