From 9441e536535af3e71aaa81801645ab42bd07e89f Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 18 Apr 2013 22:22:04 +0300 Subject: [PATCH 1/9] MDEV-4345 Sampling of selectivity of LIKE predicate. --- mysql-test/r/mysqld--help.result | 8 +- mysql-test/r/selectivity.result | 83 +++++++++++++++++++++ mysql-test/r/selectivity_innodb.result | 83 +++++++++++++++++++++ mysql-test/suite/sys_vars/r/all_vars.result | 1 + mysql-test/t/selectivity.test | 59 ++++++++++++++- sql/item.h | 15 ++++ sql/item_cmpfunc.cc | 33 ++++++++ sql/item_cmpfunc.h | 8 +- sql/opt_range.cc | 69 ++++++++++++++++- sql/opt_range.h | 7 ++ sql/sql_class.h | 1 + sql/sql_select.cc | 72 ++++++++++++++++++ sql/sql_select.h | 13 ++++ sql/sys_vars.cc | 15 +++- sql/table.cc | 1 + sql/table.h | 3 + 16 files changed, 464 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result index ff54af125e0..e1d9fe4e2fd 100644 --- a/mysql-test/r/mysqld--help.result +++ b/mysql-test/r/mysqld--help.result @@ -499,6 +499,9 @@ The following options may be given as the first argument: optimizer will switch to the original find_best search. NOTE: The value 63 and its associated behaviour is deprecated + --optimizer-selectivity-sampling-limit=# + Controls number of record samples to check condition + selectivity --optimizer-switch=name optimizer_switch=option=val[,option=val...], where option is one of {derived_merge, derived_with_keys, firstmatch, @@ -527,7 +530,9 @@ The following options may be given as the first argument: any index to calculate the cardinality of a partial join, 4 - use histograms to calculate selectivity of range conditions that are not backed by any index to calculate - the cardinality of a partial join. + the cardinality of a partial join.5 - additionally use + selectivity of certain non-range predicates calculated on + record samples --performance-schema Enable the performance schema. --performance-schema-events-waits-history-long-size=# @@ -1053,6 +1058,7 @@ old-passwords FALSE old-style-user-limits FALSE optimizer-prune-level 1 optimizer-search-depth 62 +optimizer-selectivity-sampling-limit 5000 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 diff --git a/mysql-test/r/selectivity.result b/mysql-test/r/selectivity.result index 79ff506d603..512ef4ffc1b 100644 --- a/mysql-test/r/selectivity.result +++ b/mysql-test/r/selectivity.result @@ -37,6 +37,89 @@ set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivit DROP DATABASE IF EXISTS dbt3_s001; CREATE DATABASE dbt3_s001; use dbt3_s001; +=== Q2 === +set optimizer_use_condition_selectivity=5; +explain extended +select +s_acctbal, s_name, n_name, p_partkey, p_mfgr, s_address, s_phone, s_comment +from +part, supplier, partsupp, nation, region +where +p_partkey = ps_partkey +and s_suppkey = ps_suppkey +and p_size = 9 +and p_type like '%TIN' + and s_nationkey = n_nationkey +and n_regionkey = r_regionkey +and r_name = 'ASIA' + and ps_supplycost = ( +select +min(ps_supplycost) +from +partsupp, supplier, nation, region +where +p_partkey = ps_partkey +and s_suppkey = ps_suppkey +and s_nationkey = n_nationkey +and n_regionkey = r_regionkey +and r_name = 'ASIA' + ) +order by +s_acctbal desc, n_name, s_name, p_partkey; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 0.31 Using where; Using temporary; Using filesort +1 PRIMARY region ALL PRIMARY NULL NULL NULL 5 20.00 Using where; Using join buffer (flat, BNL join) +1 PRIMARY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 Using where +1 PRIMARY supplier ALL PRIMARY,i_s_nationkey NULL NULL NULL 10 80.00 Using where; Using join buffer (flat, BNL join) +1 PRIMARY nation eq_ref PRIMARY,i_n_regionkey PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 100.00 Using where +2 DEPENDENT SUBQUERY region ALL PRIMARY NULL NULL NULL 5 20.00 Using where +2 DEPENDENT SUBQUERY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 +2 DEPENDENT SUBQUERY supplier eq_ref PRIMARY,i_s_nationkey PRIMARY 4 dbt3_s001.partsupp.ps_suppkey 1 100.00 Using where +2 DEPENDENT SUBQUERY nation eq_ref PRIMARY,i_n_regionkey PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 100.00 Using where +Warnings: +Note 1276 Field or reference 'dbt3_s001.part.p_partkey' of SELECT #2 was resolved in SELECT #1 +Note 1003 select `dbt3_s001`.`supplier`.`s_acctbal` AS `s_acctbal`,`dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`nation`.`n_name` AS `n_name`,`dbt3_s001`.`part`.`p_partkey` AS `p_partkey`,`dbt3_s001`.`part`.`p_mfgr` AS `p_mfgr`,`dbt3_s001`.`supplier`.`s_address` AS `s_address`,`dbt3_s001`.`supplier`.`s_phone` AS `s_phone`,`dbt3_s001`.`supplier`.`s_comment` AS `s_comment` from `dbt3_s001`.`part` join `dbt3_s001`.`supplier` join `dbt3_s001`.`partsupp` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where ((`dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey`) and (`dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey`) and (`dbt3_s001`.`part`.`p_size` = 9) and (`dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey`) and (`dbt3_s001`.`nation`.`n_regionkey` = `dbt3_s001`.`region`.`r_regionkey`) and (`dbt3_s001`.`region`.`r_name` = 'ASIA') and (`dbt3_s001`.`part`.`p_type` like '%TIN') and (`dbt3_s001`.`partsupp`.`ps_supplycost` = <`dbt3_s001`.`part`.`p_partkey`>((select min(`dbt3_s001`.`partsupp`.`ps_supplycost`) from `dbt3_s001`.`partsupp` join `dbt3_s001`.`supplier` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where ((`dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey`) and (`dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey`) and (`dbt3_s001`.`nation`.`n_regionkey` = `dbt3_s001`.`region`.`r_regionkey`) and (`dbt3_s001`.`region`.`r_name` = 'ASIA') and (`dbt3_s001`.`part`.`p_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey`)))))) order by `dbt3_s001`.`supplier`.`s_acctbal` desc,`dbt3_s001`.`nation`.`n_name`,`dbt3_s001`.`supplier`.`s_name`,`dbt3_s001`.`part`.`p_partkey` +set optimizer_use_condition_selectivity=4; +explain extended +select +s_acctbal, s_name, n_name, p_partkey, p_mfgr, s_address, s_phone, s_comment +from +part, supplier, partsupp, nation, region +where +p_partkey = ps_partkey +and s_suppkey = ps_suppkey +and p_size = 9 +and p_type like '%TIN' + and s_nationkey = n_nationkey +and n_regionkey = r_regionkey +and r_name = 'ASIA' + and ps_supplycost = ( +select +min(ps_supplycost) +from +partsupp, supplier, nation, region +where +p_partkey = ps_partkey +and s_suppkey = ps_suppkey +and s_nationkey = n_nationkey +and n_regionkey = r_regionkey +and r_name = 'ASIA' + ) +order by +s_acctbal desc, n_name, s_name, p_partkey; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY region ALL PRIMARY NULL NULL NULL 5 20.00 Using where; Using temporary; Using filesort +1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 2.08 Using where; Using join buffer (flat, BNL join) +1 PRIMARY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 Using where +1 PRIMARY supplier ALL PRIMARY,i_s_nationkey NULL NULL NULL 10 80.00 Using where; Using join buffer (flat, BNL join) +1 PRIMARY nation eq_ref PRIMARY,i_n_regionkey PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 100.00 Using where +2 DEPENDENT SUBQUERY region ALL PRIMARY NULL NULL NULL 5 20.00 Using where +2 DEPENDENT SUBQUERY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 +2 DEPENDENT SUBQUERY supplier eq_ref PRIMARY,i_s_nationkey PRIMARY 4 dbt3_s001.partsupp.ps_suppkey 1 100.00 Using where +2 DEPENDENT SUBQUERY nation eq_ref PRIMARY,i_n_regionkey PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 100.00 Using where +Warnings: +Note 1276 Field or reference 'dbt3_s001.part.p_partkey' of SELECT #2 was resolved in SELECT #1 +Note 1003 select `dbt3_s001`.`supplier`.`s_acctbal` AS `s_acctbal`,`dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`nation`.`n_name` AS `n_name`,`dbt3_s001`.`part`.`p_partkey` AS `p_partkey`,`dbt3_s001`.`part`.`p_mfgr` AS `p_mfgr`,`dbt3_s001`.`supplier`.`s_address` AS `s_address`,`dbt3_s001`.`supplier`.`s_phone` AS `s_phone`,`dbt3_s001`.`supplier`.`s_comment` AS `s_comment` from `dbt3_s001`.`part` join `dbt3_s001`.`supplier` join `dbt3_s001`.`partsupp` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where ((`dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey`) and (`dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey`) and (`dbt3_s001`.`part`.`p_size` = 9) and (`dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey`) and (`dbt3_s001`.`nation`.`n_regionkey` = `dbt3_s001`.`region`.`r_regionkey`) and (`dbt3_s001`.`region`.`r_name` = 'ASIA') and (`dbt3_s001`.`part`.`p_type` like '%TIN') and (`dbt3_s001`.`partsupp`.`ps_supplycost` = <`dbt3_s001`.`part`.`p_partkey`>((select min(`dbt3_s001`.`partsupp`.`ps_supplycost`) from `dbt3_s001`.`partsupp` join `dbt3_s001`.`supplier` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where ((`dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey`) and (`dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey`) and (`dbt3_s001`.`nation`.`n_regionkey` = `dbt3_s001`.`region`.`r_regionkey`) and (`dbt3_s001`.`region`.`r_name` = 'ASIA') and (`dbt3_s001`.`part`.`p_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey`)))))) order by `dbt3_s001`.`supplier`.`s_acctbal` desc,`dbt3_s001`.`nation`.`n_name`,`dbt3_s001`.`supplier`.`s_name`,`dbt3_s001`.`part`.`p_partkey` === Q15 === create view revenue0 (supplier_no, total_revenue) as select l_suppkey, sum(l_extendedprice * (1 - l_discount)) diff --git a/mysql-test/r/selectivity_innodb.result b/mysql-test/r/selectivity_innodb.result index e32eea8827d..2dce973a587 100644 --- a/mysql-test/r/selectivity_innodb.result +++ b/mysql-test/r/selectivity_innodb.result @@ -40,6 +40,89 @@ set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivit DROP DATABASE IF EXISTS dbt3_s001; CREATE DATABASE dbt3_s001; use dbt3_s001; +=== Q2 === +set optimizer_use_condition_selectivity=5; +explain extended +select +s_acctbal, s_name, n_name, p_partkey, p_mfgr, s_address, s_phone, s_comment +from +part, supplier, partsupp, nation, region +where +p_partkey = ps_partkey +and s_suppkey = ps_suppkey +and p_size = 9 +and p_type like '%TIN' + and s_nationkey = n_nationkey +and n_regionkey = r_regionkey +and r_name = 'ASIA' + and ps_supplycost = ( +select +min(ps_supplycost) +from +partsupp, supplier, nation, region +where +p_partkey = ps_partkey +and s_suppkey = ps_suppkey +and s_nationkey = n_nationkey +and n_regionkey = r_regionkey +and r_name = 'ASIA' + ) +order by +s_acctbal desc, n_name, s_name, p_partkey; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 0.31 Using where; Using temporary; Using filesort +1 PRIMARY region ALL PRIMARY NULL NULL NULL 5 20.00 Using where; Using join buffer (flat, BNL join) +1 PRIMARY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 Using where +1 PRIMARY supplier ALL PRIMARY,i_s_nationkey NULL NULL NULL 10 80.00 Using where; Using join buffer (flat, BNL join) +1 PRIMARY nation eq_ref PRIMARY,i_n_regionkey PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 100.00 Using where +2 DEPENDENT SUBQUERY region ALL PRIMARY NULL NULL NULL 5 20.00 Using where +2 DEPENDENT SUBQUERY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 +2 DEPENDENT SUBQUERY supplier eq_ref PRIMARY,i_s_nationkey PRIMARY 4 dbt3_s001.partsupp.ps_suppkey 1 100.00 Using where +2 DEPENDENT SUBQUERY nation eq_ref PRIMARY,i_n_regionkey PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 100.00 Using where +Warnings: +Note 1276 Field or reference 'dbt3_s001.part.p_partkey' of SELECT #2 was resolved in SELECT #1 +Note 1003 select `dbt3_s001`.`supplier`.`s_acctbal` AS `s_acctbal`,`dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`nation`.`n_name` AS `n_name`,`dbt3_s001`.`part`.`p_partkey` AS `p_partkey`,`dbt3_s001`.`part`.`p_mfgr` AS `p_mfgr`,`dbt3_s001`.`supplier`.`s_address` AS `s_address`,`dbt3_s001`.`supplier`.`s_phone` AS `s_phone`,`dbt3_s001`.`supplier`.`s_comment` AS `s_comment` from `dbt3_s001`.`part` join `dbt3_s001`.`supplier` join `dbt3_s001`.`partsupp` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where ((`dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey`) and (`dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey`) and (`dbt3_s001`.`part`.`p_size` = 9) and (`dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey`) and (`dbt3_s001`.`nation`.`n_regionkey` = `dbt3_s001`.`region`.`r_regionkey`) and (`dbt3_s001`.`region`.`r_name` = 'ASIA') and (`dbt3_s001`.`part`.`p_type` like '%TIN') and (`dbt3_s001`.`partsupp`.`ps_supplycost` = <`dbt3_s001`.`part`.`p_partkey`>((select min(`dbt3_s001`.`partsupp`.`ps_supplycost`) from `dbt3_s001`.`partsupp` join `dbt3_s001`.`supplier` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where ((`dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey`) and (`dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey`) and (`dbt3_s001`.`nation`.`n_regionkey` = `dbt3_s001`.`region`.`r_regionkey`) and (`dbt3_s001`.`region`.`r_name` = 'ASIA') and (`dbt3_s001`.`part`.`p_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey`)))))) order by `dbt3_s001`.`supplier`.`s_acctbal` desc,`dbt3_s001`.`nation`.`n_name`,`dbt3_s001`.`supplier`.`s_name`,`dbt3_s001`.`part`.`p_partkey` +set optimizer_use_condition_selectivity=4; +explain extended +select +s_acctbal, s_name, n_name, p_partkey, p_mfgr, s_address, s_phone, s_comment +from +part, supplier, partsupp, nation, region +where +p_partkey = ps_partkey +and s_suppkey = ps_suppkey +and p_size = 9 +and p_type like '%TIN' + and s_nationkey = n_nationkey +and n_regionkey = r_regionkey +and r_name = 'ASIA' + and ps_supplycost = ( +select +min(ps_supplycost) +from +partsupp, supplier, nation, region +where +p_partkey = ps_partkey +and s_suppkey = ps_suppkey +and s_nationkey = n_nationkey +and n_regionkey = r_regionkey +and r_name = 'ASIA' + ) +order by +s_acctbal desc, n_name, s_name, p_partkey; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY region ALL PRIMARY NULL NULL NULL 5 20.00 Using where; Using temporary; Using filesort +1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 2.08 Using where; Using join buffer (flat, BNL join) +1 PRIMARY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 Using where +1 PRIMARY supplier ALL PRIMARY,i_s_nationkey NULL NULL NULL 10 80.00 Using where; Using join buffer (flat, BNL join) +1 PRIMARY nation eq_ref PRIMARY,i_n_regionkey PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 100.00 Using where +2 DEPENDENT SUBQUERY region ALL PRIMARY NULL NULL NULL 5 20.00 Using where +2 DEPENDENT SUBQUERY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 +2 DEPENDENT SUBQUERY supplier eq_ref PRIMARY,i_s_nationkey PRIMARY 4 dbt3_s001.partsupp.ps_suppkey 1 100.00 Using where +2 DEPENDENT SUBQUERY nation eq_ref PRIMARY,i_n_regionkey PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 100.00 Using where +Warnings: +Note 1276 Field or reference 'dbt3_s001.part.p_partkey' of SELECT #2 was resolved in SELECT #1 +Note 1003 select `dbt3_s001`.`supplier`.`s_acctbal` AS `s_acctbal`,`dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`nation`.`n_name` AS `n_name`,`dbt3_s001`.`part`.`p_partkey` AS `p_partkey`,`dbt3_s001`.`part`.`p_mfgr` AS `p_mfgr`,`dbt3_s001`.`supplier`.`s_address` AS `s_address`,`dbt3_s001`.`supplier`.`s_phone` AS `s_phone`,`dbt3_s001`.`supplier`.`s_comment` AS `s_comment` from `dbt3_s001`.`part` join `dbt3_s001`.`supplier` join `dbt3_s001`.`partsupp` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where ((`dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey`) and (`dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey`) and (`dbt3_s001`.`part`.`p_size` = 9) and (`dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey`) and (`dbt3_s001`.`nation`.`n_regionkey` = `dbt3_s001`.`region`.`r_regionkey`) and (`dbt3_s001`.`region`.`r_name` = 'ASIA') and (`dbt3_s001`.`part`.`p_type` like '%TIN') and (`dbt3_s001`.`partsupp`.`ps_supplycost` = <`dbt3_s001`.`part`.`p_partkey`>((select min(`dbt3_s001`.`partsupp`.`ps_supplycost`) from `dbt3_s001`.`partsupp` join `dbt3_s001`.`supplier` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where ((`dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey`) and (`dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey`) and (`dbt3_s001`.`nation`.`n_regionkey` = `dbt3_s001`.`region`.`r_regionkey`) and (`dbt3_s001`.`region`.`r_name` = 'ASIA') and (`dbt3_s001`.`part`.`p_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey`)))))) order by `dbt3_s001`.`supplier`.`s_acctbal` desc,`dbt3_s001`.`nation`.`n_name`,`dbt3_s001`.`supplier`.`s_name`,`dbt3_s001`.`part`.`p_partkey` === Q15 === create view revenue0 (supplier_no, total_revenue) as select l_suppkey, sum(l_extendedprice * (1 - l_discount)) diff --git a/mysql-test/suite/sys_vars/r/all_vars.result b/mysql-test/suite/sys_vars/r/all_vars.result index 1bd4e394f6a..7beccc4d3bf 100644 --- a/mysql-test/suite/sys_vars/r/all_vars.result +++ b/mysql-test/suite/sys_vars/r/all_vars.result @@ -10,5 +10,6 @@ there should be *no* long test name listed below: select distinct variable_name as `there should be *no* variables listed below:` from t2 left join t1 on variable_name=test_name where test_name is null; there should be *no* variables listed below: +optimizer_selectivity_sampling_limit drop table t1; drop table t2; diff --git a/mysql-test/t/selectivity.test b/mysql-test/t/selectivity.test index 56908e50c65..8bde4718fdd 100644 --- a/mysql-test/t/selectivity.test +++ b/mysql-test/t/selectivity.test @@ -56,6 +56,64 @@ customer, lineitem, nation, orders, part, partsupp, region, supplier; --enable_result_log --enable_query_log +--echo === Q2 === + +set optimizer_use_condition_selectivity=5; +explain extended +select + s_acctbal, s_name, n_name, p_partkey, p_mfgr, s_address, s_phone, s_comment +from + part, supplier, partsupp, nation, region +where + p_partkey = ps_partkey + and s_suppkey = ps_suppkey + and p_size = 9 + and p_type like '%TIN' + and s_nationkey = n_nationkey + and n_regionkey = r_regionkey + and r_name = 'ASIA' + and ps_supplycost = ( + select + min(ps_supplycost) + from + partsupp, supplier, nation, region + where + p_partkey = ps_partkey + and s_suppkey = ps_suppkey + and s_nationkey = n_nationkey + and n_regionkey = r_regionkey + and r_name = 'ASIA' + ) +order by + s_acctbal desc, n_name, s_name, p_partkey; +set optimizer_use_condition_selectivity=4; +explain extended +select + s_acctbal, s_name, n_name, p_partkey, p_mfgr, s_address, s_phone, s_comment +from + part, supplier, partsupp, nation, region +where + p_partkey = ps_partkey + and s_suppkey = ps_suppkey + and p_size = 9 + and p_type like '%TIN' + and s_nationkey = n_nationkey + and n_regionkey = r_regionkey + and r_name = 'ASIA' + and ps_supplycost = ( + select + min(ps_supplycost) + from + partsupp, supplier, nation, region + where + p_partkey = ps_partkey + and s_suppkey = ps_suppkey + and s_nationkey = n_nationkey + and n_regionkey = r_regionkey + and r_name = 'ASIA' + ) +order by + s_acctbal desc, n_name, s_name, p_partkey; --echo === Q15 === @@ -230,7 +288,6 @@ flush table nation; eval EXPLAIN EXTENDED $Q20; eval $Q20; - DROP DATABASE dbt3_s001; set histogram_type=@save_histogram_type; diff --git a/sql/item.h b/sql/item.h index 50d125f76de..d8ae051b4b5 100644 --- a/sql/item.h +++ b/sql/item.h @@ -548,6 +548,14 @@ typedef bool (Item::*Item_analyzer) (uchar **argp); typedef Item* (Item::*Item_transformer) (uchar *arg); typedef void (*Cond_traverser) (const Item *item, void *arg); +struct st_cond_statistic; + +struct find_selective_predicates_list_processor_data +{ + TABLE *table; + List list; +}; + class Item_equal; class COND_EQUAL; @@ -1108,6 +1116,11 @@ public: return (this->*processor)(arg); } + virtual bool walk_top_and(Item_processor processor, uchar *arg) + { + return (this->*processor)(arg); + } + virtual Item* transform(Item_transformer transformer, uchar *arg); /* @@ -1174,6 +1187,8 @@ public: return FALSE; } virtual bool exists2in_processor(uchar *opt_arg) { return 0; } + virtual bool find_selective_predicates_list_processor(uchar *opt_arg) + { return 0; } /* To call bool function for all arguments */ struct bool_func_call_args diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index b5b143a2448..7ca85a72cfa 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -4428,6 +4428,16 @@ bool Item_cond::walk(Item_processor processor, bool walk_subquery, uchar *arg) return Item_func::walk(processor, walk_subquery, arg); } +bool Item_cond_and::walk_top_and(Item_processor processor, uchar *arg) +{ + List_iterator_fast li(list); + Item *item; + while ((item= li++)) + if (item->walk_top_and(processor, arg)) + return 1; + return Item_cond::walk_top_and(processor, arg); +} + /** Transform an Item_cond object with a transformer callback function. @@ -4940,6 +4950,7 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref) turboBM_compute_bad_character_shifts(); DBUG_PRINT("info",("done")); } + use_sampling= ((*first == wild_many || *first == wild_one) && len > 2); } } return FALSE; @@ -4951,6 +4962,28 @@ void Item_func_like::cleanup() Item_bool_func2::cleanup(); } + +bool Item_func_like::find_selective_predicates_list_processor(uchar *arg) +{ + find_selective_predicates_list_processor_data *data= + (find_selective_predicates_list_processor_data *) arg; + if (use_sampling && used_tables() == data->table->map) + { + COND_STATISTIC *stat= (COND_STATISTIC *)sql_alloc(sizeof(COND_STATISTIC)); + if (!stat) + return TRUE; + stat->cond= this; + Item *arg0= args[0]->real_item(); + if (args[1]->const_item() && arg0->type() == FIELD_ITEM) + stat->field_arg= ((Item_field *)arg0)->field; + else + stat->field_arg= NULL; + data->list.push_back(stat); + } + return FALSE; +} + + /** @brief Compile regular expression. diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 81598ba96c8..ab4219564fe 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1487,8 +1487,9 @@ class Item_func_like :public Item_bool_func2 enum { alphabet_size = 256 }; Item *escape_item; - + bool escape_used_in_parsing; + bool use_sampling; public: int escape; @@ -1496,7 +1497,7 @@ public: Item_func_like(Item *a,Item *b, Item *escape_arg, bool escape_used) :Item_bool_func2(a,b), canDoTurboBM(FALSE), pattern(0), pattern_len(0), bmGs(0), bmBc(0), escape_item(escape_arg), - escape_used_in_parsing(escape_used) {} + escape_used_in_parsing(escape_used), use_sampling(0) {} longlong val_int(); enum Functype functype() const { return LIKE_FUNC; } optimize_type select_optimize() const; @@ -1504,6 +1505,8 @@ public: const char *func_name() const { return "like"; } bool fix_fields(THD *thd, Item **ref); void cleanup(); + + bool find_selective_predicates_list_processor(uchar *arg); }; @@ -1914,6 +1917,7 @@ public: Item *neg_transformer(THD *thd); void mark_as_condition_AND_part(TABLE_LIST *embedding); virtual uint exists2in_reserved_items() { return list.elements; }; + bool walk_top_and(Item_processor processor, uchar *arg); }; inline bool is_cond_and(Item *item) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index c29a888ea6f..b736f898768 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -3530,7 +3530,74 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item *cond) } } } - } + } + + /* Calculate selectivity of probably highly selective predicates */ + ulong check_rows= + min(thd->variables.optimizer_selectivity_sampling_limit, + (ulong) (table_records * SELECTIVITY_SAMPLING_SHARE)); + if (cond && check_rows > SELECTIVITY_SAMPLING_THRESHOLD && + thd->variables.optimizer_use_condition_selectivity > 4) + { + find_selective_predicates_list_processor_data *dt= + (find_selective_predicates_list_processor_data *) + alloc_root(thd->mem_root, + sizeof(find_selective_predicates_list_processor_data)); + if (!dt) + DBUG_RETURN(TRUE); + dt->list.empty(); + dt->table= table; + if (cond->walk(&Item::find_selective_predicates_list_processor, 0, + (uchar*) dt)) + DBUG_RETURN(TRUE); + if (dt->list.elements > 0) + { + check_rows= check_selectivity(thd, check_rows, table, &dt->list); + if (check_rows > SELECTIVITY_SAMPLING_THRESHOLD) + { + COND_STATISTIC *stat; + List_iterator_fast it(dt->list); + double examined_rows= check_rows; + while ((stat= it++)) + { + if (!stat->positive) + { + DBUG_PRINT("info", ("To avoid 0 assigned 1 to the counter")); + stat->positive= 1; // avoid 0 + } + DBUG_PRINT("info", ("The predicate selectivity : %g", + (double)stat->positive / examined_rows)); + double selectivity= ((double)stat->positive) / examined_rows; + table->cond_selectivity*= selectivity; + /* + If a field is involved then we register its selectivity in case + there in an equality with the field. + For example in case + t1.a LIKE "%bla%" and t1.a = t2.b + the selectivity we have found could be used also for t2. + */ + if (stat->field_arg) + { + stat->field_arg->cond_selectivity*= selectivity; + + if (stat->field_arg->next_equal_field) + { + for (Field *next_field= stat->field_arg->next_equal_field; + next_field != stat->field_arg; + next_field= next_field->next_equal_field) + { + next_field->cond_selectivity*= selectivity; + next_field->table->cond_selectivity*= selectivity; + } + } + } + } + + } + /* This list and its elements put to mem_root so should not be freed */ + table->cond_selectivity_sampling_explain= &dt->list; + } + } DBUG_RETURN(FALSE); } diff --git a/sql/opt_range.h b/sql/opt_range.h index d98bf1186e8..963551cabdb 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -1051,4 +1051,11 @@ void store_key_image_to_rec(Field *field, uchar *ptr, uint len); extern String null_string; +/* check this number of rows (default value) */ +#define SELECTIVITY_SAMPLING_LIMIT 5000 +/* but no more then this part of table (10%) */ +#define SELECTIVITY_SAMPLING_SHARE 0.10 +/* do not check if we are going check less then this number of records */ +#define SELECTIVITY_SAMPLING_THRESHOLD 10 + #endif diff --git a/sql/sql_class.h b/sql/sql_class.h index 8e2bd59da57..bb5b2c4e775 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -505,6 +505,7 @@ typedef struct system_variables ulong net_write_timeout; ulong optimizer_prune_level; ulong optimizer_search_depth; + ulong optimizer_selectivity_sampling_limit; ulong optimizer_use_condition_selectivity; ulong use_stat_tables; ulong histogram_size; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index cc4b139fb2f..a48eff66386 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -23972,6 +23972,78 @@ uint get_index_for_order(ORDER *order, TABLE *table, SQL_SELECT *select, return MAX_KEY; } +/* + Count how much times conditions are true for several first rows of the table + + @param thd thread handle + @param rows_to_read how much rows to check + @param table table which should be checked + @conds conds list of conditions and countars for them + + @return number of really checked rows or 0 in case of error or empty table +*/ + +ulong check_selectivity(THD *thd, + ulong rows_to_read, + TABLE *table, + List *conds) +{ + ulong count= 0; + COND_STATISTIC *cond; + List_iterator_fast it(*conds); + handler *file= table->file; + uchar *record= table->record[0]; + int error= 0; + DBUG_ENTER("check_selectivity"); + + DBUG_ASSERT(rows_to_read > 0); + while ((cond= it++)) + { + DBUG_ASSERT(cond->cond); + DBUG_ASSERT(cond->cond->used_tables() == table->map); + cond->positive= 0; + } + it.rewind(); + + if (file->ha_rnd_init_with_error(1)) + DBUG_RETURN(0); + do + { + error= file->ha_rnd_next(record); + + if (thd->killed) + { + thd->send_kill_message(); + count= 0; + goto err; + } + if (error) + { + if (error == HA_ERR_RECORD_DELETED) + continue; + if (error == HA_ERR_END_OF_FILE) + break; + goto err; + } + + count++; + while ((cond= it++)) + { + if (cond->cond->val_bool()) + cond->positive++; + } + it.rewind(); + + } while (count < rows_to_read); + + file->ha_rnd_end(); + DBUG_RETURN(count); + +err: + DBUG_PRINT("error", ("error %d", error)); + file->ha_rnd_end(); + DBUG_RETURN(0); +} /** @} (end of group Query_Optimizer) diff --git a/sql/sql_select.h b/sql/sql_select.h index 9cda68bd434..950c48d6ea1 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1855,4 +1855,17 @@ void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps); double prev_record_reads(POSITION *positions, uint idx, table_map found_ref); void fix_list_after_tbl_changes(SELECT_LEX *new_parent, List *tlist); +struct st_cond_statistic +{ + Item *cond; + Field *field_arg; + ulong positive; +}; +typedef struct st_cond_statistic COND_STATISTIC; + +ulong check_selectivity(THD *thd, + ulong rows_to_read, + TABLE *table, + List *conds); + #endif /* SQL_SELECT_INCLUDED */ diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 4393809a6fe..24009cb5a99 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -56,6 +56,7 @@ #endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */ #include "threadpool.h" #include "sql_repl.h" +#include "opt_range.h" /* The rule for this file: everything should be 'static'. When a sys_var @@ -1533,6 +1534,14 @@ 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_selectivity_sampling_limit( + "optimizer_selectivity_sampling_limit", + "Controls number of record samples to check condition selectivity", + SESSION_VAR(optimizer_selectivity_sampling_limit), + CMD_LINE(REQUIRED_ARG), + VALID_RANGE(SELECTIVITY_SAMPLING_THRESHOLD, UINT_MAX), + DEFAULT(SELECTIVITY_SAMPLING_LIMIT), 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 " @@ -1548,9 +1557,11 @@ static Sys_var_ulong Sys_optimizer_use_condition_selectivity( "not backed by any index to calculate the cardinality of a partial join, " "4 - use histograms to calculate selectivity of range conditions that " "are not backed by any index to calculate the cardinality of " - "a partial join.", + "a partial join." + "5 - additionally use selectivity of certain non-range predicates " + "calculated on record samples", SESSION_VAR(optimizer_use_condition_selectivity), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(1, 4), DEFAULT(1), BLOCK_SIZE(1)); + VALID_RANGE(1, 5), DEFAULT(1), BLOCK_SIZE(1)); /** Warns about deprecated value 63 */ static bool fix_optimizer_search_depth(sys_var *self, THD *thd, diff --git a/sql/table.cc b/sql/table.cc index e88b3453ce9..caed8ed4107 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -3891,6 +3891,7 @@ void TABLE::init(THD *thd, TABLE_LIST *tl) reginfo.impossible_range= 0; created= TRUE; cond_selectivity= 1.0; + cond_selectivity_sampling_explain= NULL; /* Catch wrong handling of the auto_increment_field_not_null. */ DBUG_ASSERT(!auto_increment_field_not_null); diff --git a/sql/table.h b/sql/table.h index e721d60f892..af79bffd437 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1038,6 +1038,8 @@ enum index_hint_type INDEX_HINT_FORCE }; +struct st_cond_statistic; + #define CHECK_ROW_FOR_NULLS_TO_REJECT (1 << 0) #define REJECT_ROW_DUE_TO_NULL_FIELDS (1 << 1) @@ -1163,6 +1165,7 @@ public: ha_rows quick_condition_rows; double cond_selectivity; + List *cond_selectivity_sampling_explain; table_map map; /* ID bit of table (1,2,4,8,16...) */ From c44c923156e9eb380121048dc589893fdd0e3081 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Apr 2013 18:59:46 +0300 Subject: [PATCH 2/9] MDEV-4345: Fixed system variables tests. --- mysql-test/suite/sys_vars/r/all_vars.result | 1 - ...er_selectivity_sampling_limit_basic.result | 141 ++++++++++++++++ ...zer_use_condition_selectivity_basic.result | 32 ++++ ...izer_selectivity_sampling_limit_basic.test | 154 ++++++++++++++++++ ...mizer_use_condition_selectivity_basic.test | 12 ++ 5 files changed, 339 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/sys_vars/r/optimizer_selectivity_sampling_limit_basic.result create mode 100644 mysql-test/suite/sys_vars/t/optimizer_selectivity_sampling_limit_basic.test diff --git a/mysql-test/suite/sys_vars/r/all_vars.result b/mysql-test/suite/sys_vars/r/all_vars.result index 7beccc4d3bf..1bd4e394f6a 100644 --- a/mysql-test/suite/sys_vars/r/all_vars.result +++ b/mysql-test/suite/sys_vars/r/all_vars.result @@ -10,6 +10,5 @@ there should be *no* long test name listed below: select distinct variable_name as `there should be *no* variables listed below:` from t2 left join t1 on variable_name=test_name where test_name is null; there should be *no* variables listed below: -optimizer_selectivity_sampling_limit drop table t1; drop table t2; diff --git a/mysql-test/suite/sys_vars/r/optimizer_selectivity_sampling_limit_basic.result b/mysql-test/suite/sys_vars/r/optimizer_selectivity_sampling_limit_basic.result new file mode 100644 index 00000000000..5df07b8f899 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/optimizer_selectivity_sampling_limit_basic.result @@ -0,0 +1,141 @@ +SET @start_global_value = @@global.optimizer_selectivity_sampling_limit; +SELECT @start_global_value; +@start_global_value +5000 +SET @start_session_value = @@session.optimizer_selectivity_sampling_limit; +SELECT @start_session_value; +@start_session_value +5000 +'#--------------------FN_DYNVARS_115_01-------------------------#' +SET @@global.optimizer_selectivity_sampling_limit = DEFAULT; +SELECT @@global.optimizer_selectivity_sampling_limit; +@@global.optimizer_selectivity_sampling_limit +5000 +SET @@session.optimizer_selectivity_sampling_limit = DEFAULT; +SELECT @@session.optimizer_selectivity_sampling_limit; +@@session.optimizer_selectivity_sampling_limit +5000 +'#--------------------FN_DYNVARS_115_02-------------------------#' +SET @@global.optimizer_selectivity_sampling_limit = DEFAULT; +SELECT @@global.optimizer_selectivity_sampling_limit = 5000; +@@global.optimizer_selectivity_sampling_limit = 5000 +1 +SET @@session.optimizer_selectivity_sampling_limit = DEFAULT; +SELECT @@session.optimizer_selectivity_sampling_limit = 5000; +@@session.optimizer_selectivity_sampling_limit = 5000 +1 +'#--------------------FN_DYNVARS_115_03-------------------------#' +SELECT @@global.optimizer_selectivity_sampling_limit; +@@global.optimizer_selectivity_sampling_limit +5000 +SET @@global.optimizer_selectivity_sampling_limit = 9; +Warnings: +Warning 1292 Truncated incorrect optimizer_selectivity_sampling_l value: '9' +SELECT @@global.optimizer_selectivity_sampling_limit; +@@global.optimizer_selectivity_sampling_limit +10 +SET @@global.optimizer_selectivity_sampling_limit = 10; +SELECT @@global.optimizer_selectivity_sampling_limit; +@@global.optimizer_selectivity_sampling_limit +10 +SET @@global.optimizer_selectivity_sampling_limit = 11; +SELECT @@global.optimizer_selectivity_sampling_limit; +@@global.optimizer_selectivity_sampling_limit +11 +SET @@global.optimizer_selectivity_sampling_limit = 7777; +SELECT @@global.optimizer_selectivity_sampling_limit; +@@global.optimizer_selectivity_sampling_limit +7777 +SET @@global.optimizer_selectivity_sampling_limit = 4294967294; +SELECT @@global.optimizer_selectivity_sampling_limit; +@@global.optimizer_selectivity_sampling_limit +4294967294 +SET @@global.optimizer_selectivity_sampling_limit = 4294967295; +SELECT @@global.optimizer_selectivity_sampling_limit; +@@global.optimizer_selectivity_sampling_limit +4294967295 +SET @@global.optimizer_selectivity_sampling_limit = 4294967296; +Warnings: +Warning 1292 Truncated incorrect optimizer_selectivity_sampling_l value: '4294967296' +SELECT @@global.optimizer_selectivity_sampling_limit; +@@global.optimizer_selectivity_sampling_limit +4294967295 +'#--------------------FN_DYNVARS_115_04-------------------------#' +SELECT @@session.optimizer_selectivity_sampling_limit; +@@session.optimizer_selectivity_sampling_limit +5000 +SET @@session.optimizer_selectivity_sampling_limit = 9; +Warnings: +Warning 1292 Truncated incorrect optimizer_selectivity_sampling_l value: '9' +SELECT @@session.optimizer_selectivity_sampling_limit; +@@session.optimizer_selectivity_sampling_limit +10 +SET @@session.optimizer_selectivity_sampling_limit = 10; +SELECT @@session.optimizer_selectivity_sampling_limit; +@@session.optimizer_selectivity_sampling_limit +10 +SET @@session.optimizer_selectivity_sampling_limit = 11; +SELECT @@session.optimizer_selectivity_sampling_limit; +@@session.optimizer_selectivity_sampling_limit +11 +SET @@session.optimizer_selectivity_sampling_limit = 7777; +SELECT @@session.optimizer_selectivity_sampling_limit; +@@session.optimizer_selectivity_sampling_limit +7777 +SET @@session.optimizer_selectivity_sampling_limit = 4294967294; +SELECT @@session.optimizer_selectivity_sampling_limit; +@@session.optimizer_selectivity_sampling_limit +4294967294 +SET @@session.optimizer_selectivity_sampling_limit = 4294967295; +SELECT @@session.optimizer_selectivity_sampling_limit; +@@session.optimizer_selectivity_sampling_limit +4294967295 +SET @@session.optimizer_selectivity_sampling_limit = 4294967296; +Warnings: +Warning 1292 Truncated incorrect optimizer_selectivity_sampling_l value: '4294967296' +SELECT @@session.optimizer_selectivity_sampling_limit; +@@session.optimizer_selectivity_sampling_limit +4294967295 +'#------------------FN_DYNVARS_115_05-----------------------#' +SET @@global.optimizer_selectivity_sampling_limit = ON; +ERROR 42000: Incorrect argument type to variable 'optimizer_selectivity_sampling_limit' +SET @@global.optimizer_selectivity_sampling_limit = OFF; +ERROR 42000: Incorrect argument type to variable 'optimizer_selectivity_sampling_limit' +SET @@session.optimizer_selectivity_sampling_limit = 65530.34; +ERROR 42000: Incorrect argument type to variable 'optimizer_selectivity_sampling_limit' +SET @@session.optimizer_selectivity_sampling_limit = test; +ERROR 42000: Incorrect argument type to variable 'optimizer_selectivity_sampling_limit' +'#------------------FN_DYNVARS_115_06-----------------------#' +SELECT @@global.optimizer_selectivity_sampling_limit = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES +WHERE VARIABLE_NAME='optimizer_selectivity_sampling_limit'; +@@global.optimizer_selectivity_sampling_limit = VARIABLE_VALUE +1 +'#------------------FN_DYNVARS_115_07-----------------------#' +SELECT @@session.optimizer_selectivity_sampling_limit = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.SESSION_VARIABLES +WHERE VARIABLE_NAME='optimizer_selectivity_sampling_limit'; +@@session.optimizer_selectivity_sampling_limit = VARIABLE_VALUE +1 +'#---------------------FN_DYNVARS_115_08----------------------#' +SET @@optimizer_selectivity_sampling_limit = 10; +SET @@global.optimizer_selectivity_sampling_limit = 30; +SELECT @@optimizer_selectivity_sampling_limit = @@global.optimizer_selectivity_sampling_limit; +@@optimizer_selectivity_sampling_limit = @@global.optimizer_selectivity_sampling_limit +0 +'#---------------------FN_DYNVARS_115_09----------------------#' +SET @@optimizer_selectivity_sampling_limit = 20; +SELECT @@optimizer_selectivity_sampling_limit = @@local.optimizer_selectivity_sampling_limit; +@@optimizer_selectivity_sampling_limit = @@local.optimizer_selectivity_sampling_limit +1 +SELECT @@local.optimizer_selectivity_sampling_limit = @@session.optimizer_selectivity_sampling_limit; +@@local.optimizer_selectivity_sampling_limit = @@session.optimizer_selectivity_sampling_limit +1 +SET @@global.optimizer_selectivity_sampling_limit = @start_global_value; +SELECT @@global.optimizer_selectivity_sampling_limit; +@@global.optimizer_selectivity_sampling_limit +5000 +SET @@session.optimizer_selectivity_sampling_limit = @start_session_value; +SELECT @@session.optimizer_selectivity_sampling_limit; +@@session.optimizer_selectivity_sampling_limit +5000 diff --git a/mysql-test/suite/sys_vars/r/optimizer_use_condition_selectivity_basic.result b/mysql-test/suite/sys_vars/r/optimizer_use_condition_selectivity_basic.result index 418c221b5aa..a030bae3750 100644 --- a/mysql-test/suite/sys_vars/r/optimizer_use_condition_selectivity_basic.result +++ b/mysql-test/suite/sys_vars/r/optimizer_use_condition_selectivity_basic.result @@ -28,6 +28,12 @@ SELECT @@session.optimizer_use_condition_selectivity = 1; SELECT @@global.optimizer_use_condition_selectivity; @@global.optimizer_use_condition_selectivity 1 +SET @@global.optimizer_use_condition_selectivity = 0; +Warnings: +Warning 1292 Truncated incorrect optimizer_use_condition_selectiv value: '0' +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 @@ -44,10 +50,26 @@ SET @@global.optimizer_use_condition_selectivity = 4; SELECT @@global.optimizer_use_condition_selectivity; @@global.optimizer_use_condition_selectivity 4 +SET @@global.optimizer_use_condition_selectivity = 5; +SELECT @@global.optimizer_use_condition_selectivity; +@@global.optimizer_use_condition_selectivity +5 +SET @@global.optimizer_use_condition_selectivity = 6; +Warnings: +Warning 1292 Truncated incorrect optimizer_use_condition_selectiv value: '6' +SELECT @@global.optimizer_use_condition_selectivity; +@@global.optimizer_use_condition_selectivity +5 '#--------------------FN_DYNVARS_115_04-------------------------#' SELECT @@session.optimizer_use_condition_selectivity; @@session.optimizer_use_condition_selectivity 1 +SET @@session.optimizer_use_condition_selectivity = 0; +Warnings: +Warning 1292 Truncated incorrect optimizer_use_condition_selectiv value: '0' +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 @@ -64,6 +86,16 @@ SET @@session.optimizer_use_condition_selectivity = 4; SELECT @@session.optimizer_use_condition_selectivity; @@session.optimizer_use_condition_selectivity 4 +SET @@session.optimizer_use_condition_selectivity = 5; +SELECT @@session.optimizer_use_condition_selectivity; +@@session.optimizer_use_condition_selectivity +5 +SET @@session.optimizer_use_condition_selectivity = 6; +Warnings: +Warning 1292 Truncated incorrect optimizer_use_condition_selectiv value: '6' +SELECT @@session.optimizer_use_condition_selectivity; +@@session.optimizer_use_condition_selectivity +5 '#------------------FN_DYNVARS_115_05-----------------------#' SET @@global.optimizer_use_condition_selectivity = ON; ERROR 42000: Incorrect argument type to variable 'optimizer_use_condition_selectivity' diff --git a/mysql-test/suite/sys_vars/t/optimizer_selectivity_sampling_limit_basic.test b/mysql-test/suite/sys_vars/t/optimizer_selectivity_sampling_limit_basic.test new file mode 100644 index 00000000000..f67eb4c367a --- /dev/null +++ b/mysql-test/suite/sys_vars/t/optimizer_selectivity_sampling_limit_basic.test @@ -0,0 +1,154 @@ + +--source include/load_sysvars.inc + +################################################################# +# START OF optimizer_selectivity_sampling_limit TESTS # +################################################################# + + +############################################################# +# Save initial value # +############################################################# + +SET @start_global_value = @@global.optimizer_selectivity_sampling_limit; +SELECT @start_global_value; +SET @start_session_value = @@session.optimizer_selectivity_sampling_limit; +SELECT @start_session_value; + + +--echo '#--------------------FN_DYNVARS_115_01-------------------------#' +######################################################################### +# Display the DEFAULT value of optimizer_selectivity_sampling_limit # +######################################################################### + +SET @@global.optimizer_selectivity_sampling_limit = DEFAULT; +SELECT @@global.optimizer_selectivity_sampling_limit; + +SET @@session.optimizer_selectivity_sampling_limit = DEFAULT; +SELECT @@session.optimizer_selectivity_sampling_limit; + + +--echo '#--------------------FN_DYNVARS_115_02-------------------------#' +######################################################################### +# Check the DEFAULT value of optimizer_selectivity_sampling_limit # +######################################################################### + +SET @@global.optimizer_selectivity_sampling_limit = DEFAULT; +SELECT @@global.optimizer_selectivity_sampling_limit = 5000; + +SET @@session.optimizer_selectivity_sampling_limit = DEFAULT; +SELECT @@session.optimizer_selectivity_sampling_limit = 5000; + + +--echo '#--------------------FN_DYNVARS_115_03-------------------------#' +############################################################################################# +# Change the value of optimizer_selectivity_sampling_limit to a valid value for GLOBAL Scope # +############################################################################################# + +SELECT @@global.optimizer_selectivity_sampling_limit; +SET @@global.optimizer_selectivity_sampling_limit = 9; +SELECT @@global.optimizer_selectivity_sampling_limit; +SET @@global.optimizer_selectivity_sampling_limit = 10; +SELECT @@global.optimizer_selectivity_sampling_limit; +SET @@global.optimizer_selectivity_sampling_limit = 11; +SELECT @@global.optimizer_selectivity_sampling_limit; +SET @@global.optimizer_selectivity_sampling_limit = 7777; +SELECT @@global.optimizer_selectivity_sampling_limit; +SET @@global.optimizer_selectivity_sampling_limit = 4294967294; +SELECT @@global.optimizer_selectivity_sampling_limit; +SET @@global.optimizer_selectivity_sampling_limit = 4294967295; +SELECT @@global.optimizer_selectivity_sampling_limit; +SET @@global.optimizer_selectivity_sampling_limit = 4294967296; +SELECT @@global.optimizer_selectivity_sampling_limit; + + +--echo '#--------------------FN_DYNVARS_115_04-------------------------#' +############################################################################################# +# Change the value of optimizer_selectivity_sampling_limit to a valid value for SESSION Scope# +############################################################################################# + +SELECT @@session.optimizer_selectivity_sampling_limit; +SET @@session.optimizer_selectivity_sampling_limit = 9; +SELECT @@session.optimizer_selectivity_sampling_limit; +SET @@session.optimizer_selectivity_sampling_limit = 10; +SELECT @@session.optimizer_selectivity_sampling_limit; +SET @@session.optimizer_selectivity_sampling_limit = 11; +SELECT @@session.optimizer_selectivity_sampling_limit; +SET @@session.optimizer_selectivity_sampling_limit = 7777; +SELECT @@session.optimizer_selectivity_sampling_limit; +SET @@session.optimizer_selectivity_sampling_limit = 4294967294; +SELECT @@session.optimizer_selectivity_sampling_limit; +SET @@session.optimizer_selectivity_sampling_limit = 4294967295; +SELECT @@session.optimizer_selectivity_sampling_limit; +SET @@session.optimizer_selectivity_sampling_limit = 4294967296; +SELECT @@session.optimizer_selectivity_sampling_limit; + + +--echo '#------------------FN_DYNVARS_115_05-----------------------#' +############################################################################### +# Change the value of optimizer_selectivity_sampling_limit to an invalid value # +############################################################################## + +--Error ER_WRONG_TYPE_FOR_VAR +SET @@global.optimizer_selectivity_sampling_limit = ON; +--Error ER_WRONG_TYPE_FOR_VAR +SET @@global.optimizer_selectivity_sampling_limit = OFF; +--Error ER_WRONG_TYPE_FOR_VAR +SET @@session.optimizer_selectivity_sampling_limit = 65530.34; +--Error ER_WRONG_TYPE_FOR_VAR +SET @@session.optimizer_selectivity_sampling_limit = test; + +--echo '#------------------FN_DYNVARS_115_06-----------------------#' +#################################################################### +# Check if the value in GLOBAL Table matches value in variable # +#################################################################### + + +SELECT @@global.optimizer_selectivity_sampling_limit = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES +WHERE VARIABLE_NAME='optimizer_selectivity_sampling_limit'; + +--echo '#------------------FN_DYNVARS_115_07-----------------------#' +#################################################################### +# Check if the value in SESSION Table matches value in variable # +#################################################################### + +SELECT @@session.optimizer_selectivity_sampling_limit = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.SESSION_VARIABLES +WHERE VARIABLE_NAME='optimizer_selectivity_sampling_limit'; + + +--echo '#---------------------FN_DYNVARS_115_08----------------------#' +############################################################################### +# Check if global and session variable are independent of each other # +############################################################################### + +SET @@optimizer_selectivity_sampling_limit = 10; +SET @@global.optimizer_selectivity_sampling_limit = 30; +SELECT @@optimizer_selectivity_sampling_limit = @@global.optimizer_selectivity_sampling_limit; + + +--echo '#---------------------FN_DYNVARS_115_09----------------------#' +############################################################################### +# Check if accessing variable with SESSION,LOCAL and without SCOPE points # +# to same session variable # +############################################################################### + +SET @@optimizer_selectivity_sampling_limit = 20; +SELECT @@optimizer_selectivity_sampling_limit = @@local.optimizer_selectivity_sampling_limit; +SELECT @@local.optimizer_selectivity_sampling_limit = @@session.optimizer_selectivity_sampling_limit; + + +#################################### +# Restore initial value # +#################################### + +SET @@global.optimizer_selectivity_sampling_limit = @start_global_value; +SELECT @@global.optimizer_selectivity_sampling_limit; +SET @@session.optimizer_selectivity_sampling_limit = @start_session_value; +SELECT @@session.optimizer_selectivity_sampling_limit; + +######################################################################## +# END OF optimizer_selectivity_sampling_limit TESTS # +######################################################################## + diff --git a/mysql-test/suite/sys_vars/t/optimizer_use_condition_selectivity_basic.test b/mysql-test/suite/sys_vars/t/optimizer_use_condition_selectivity_basic.test index 58a1af4b975..c409abd0d1b 100644 --- a/mysql-test/suite/sys_vars/t/optimizer_use_condition_selectivity_basic.test +++ b/mysql-test/suite/sys_vars/t/optimizer_use_condition_selectivity_basic.test @@ -45,6 +45,8 @@ SELECT @@session.optimizer_use_condition_selectivity = 1; # 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 = 0; SELECT @@global.optimizer_use_condition_selectivity; SET @@global.optimizer_use_condition_selectivity = 1; SELECT @@global.optimizer_use_condition_selectivity; @@ -54,6 +56,10 @@ SET @@global.optimizer_use_condition_selectivity = 3; SELECT @@global.optimizer_use_condition_selectivity; SET @@global.optimizer_use_condition_selectivity = 4; SELECT @@global.optimizer_use_condition_selectivity; +SET @@global.optimizer_use_condition_selectivity = 5; +SELECT @@global.optimizer_use_condition_selectivity; +SET @@global.optimizer_use_condition_selectivity = 6; +SELECT @@global.optimizer_use_condition_selectivity; --echo '#--------------------FN_DYNVARS_115_04-------------------------#' @@ -61,6 +67,8 @@ SELECT @@global.optimizer_use_condition_selectivity; # 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 = 0; SELECT @@session.optimizer_use_condition_selectivity; SET @@session.optimizer_use_condition_selectivity = 1; SELECT @@session.optimizer_use_condition_selectivity; @@ -70,6 +78,10 @@ SET @@session.optimizer_use_condition_selectivity = 3; SELECT @@session.optimizer_use_condition_selectivity; SET @@session.optimizer_use_condition_selectivity = 4; SELECT @@session.optimizer_use_condition_selectivity; +SET @@session.optimizer_use_condition_selectivity = 5; +SELECT @@session.optimizer_use_condition_selectivity; +SET @@session.optimizer_use_condition_selectivity = 6; +SELECT @@session.optimizer_use_condition_selectivity; --echo '#------------------FN_DYNVARS_115_05-----------------------#' From 1a8486a842f177022d7deec060b12756cb26a9fb Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Apr 2013 19:35:13 +0300 Subject: [PATCH 3/9] MDEV-4345: fixed optimizer_selectivity_sampling_limit default value. --- ...er_selectivity_sampling_limit_basic.result | 24 +++++++++---------- ...izer_selectivity_sampling_limit_basic.test | 4 ++-- sql/opt_range.h | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/mysql-test/suite/sys_vars/r/optimizer_selectivity_sampling_limit_basic.result b/mysql-test/suite/sys_vars/r/optimizer_selectivity_sampling_limit_basic.result index 5df07b8f899..4df024b9cec 100644 --- a/mysql-test/suite/sys_vars/r/optimizer_selectivity_sampling_limit_basic.result +++ b/mysql-test/suite/sys_vars/r/optimizer_selectivity_sampling_limit_basic.result @@ -1,33 +1,33 @@ SET @start_global_value = @@global.optimizer_selectivity_sampling_limit; SELECT @start_global_value; @start_global_value -5000 +100 SET @start_session_value = @@session.optimizer_selectivity_sampling_limit; SELECT @start_session_value; @start_session_value -5000 +100 '#--------------------FN_DYNVARS_115_01-------------------------#' SET @@global.optimizer_selectivity_sampling_limit = DEFAULT; SELECT @@global.optimizer_selectivity_sampling_limit; @@global.optimizer_selectivity_sampling_limit -5000 +100 SET @@session.optimizer_selectivity_sampling_limit = DEFAULT; SELECT @@session.optimizer_selectivity_sampling_limit; @@session.optimizer_selectivity_sampling_limit -5000 +100 '#--------------------FN_DYNVARS_115_02-------------------------#' SET @@global.optimizer_selectivity_sampling_limit = DEFAULT; -SELECT @@global.optimizer_selectivity_sampling_limit = 5000; -@@global.optimizer_selectivity_sampling_limit = 5000 +SELECT @@global.optimizer_selectivity_sampling_limit = 100; +@@global.optimizer_selectivity_sampling_limit = 100 1 SET @@session.optimizer_selectivity_sampling_limit = DEFAULT; -SELECT @@session.optimizer_selectivity_sampling_limit = 5000; -@@session.optimizer_selectivity_sampling_limit = 5000 +SELECT @@session.optimizer_selectivity_sampling_limit = 100; +@@session.optimizer_selectivity_sampling_limit = 100 1 '#--------------------FN_DYNVARS_115_03-------------------------#' SELECT @@global.optimizer_selectivity_sampling_limit; @@global.optimizer_selectivity_sampling_limit -5000 +100 SET @@global.optimizer_selectivity_sampling_limit = 9; Warnings: Warning 1292 Truncated incorrect optimizer_selectivity_sampling_l value: '9' @@ -63,7 +63,7 @@ SELECT @@global.optimizer_selectivity_sampling_limit; '#--------------------FN_DYNVARS_115_04-------------------------#' SELECT @@session.optimizer_selectivity_sampling_limit; @@session.optimizer_selectivity_sampling_limit -5000 +100 SET @@session.optimizer_selectivity_sampling_limit = 9; Warnings: Warning 1292 Truncated incorrect optimizer_selectivity_sampling_l value: '9' @@ -134,8 +134,8 @@ SELECT @@local.optimizer_selectivity_sampling_limit = @@session.optimizer_select SET @@global.optimizer_selectivity_sampling_limit = @start_global_value; SELECT @@global.optimizer_selectivity_sampling_limit; @@global.optimizer_selectivity_sampling_limit -5000 +100 SET @@session.optimizer_selectivity_sampling_limit = @start_session_value; SELECT @@session.optimizer_selectivity_sampling_limit; @@session.optimizer_selectivity_sampling_limit -5000 +100 diff --git a/mysql-test/suite/sys_vars/t/optimizer_selectivity_sampling_limit_basic.test b/mysql-test/suite/sys_vars/t/optimizer_selectivity_sampling_limit_basic.test index f67eb4c367a..232ff99db74 100644 --- a/mysql-test/suite/sys_vars/t/optimizer_selectivity_sampling_limit_basic.test +++ b/mysql-test/suite/sys_vars/t/optimizer_selectivity_sampling_limit_basic.test @@ -34,10 +34,10 @@ SELECT @@session.optimizer_selectivity_sampling_limit; ######################################################################### SET @@global.optimizer_selectivity_sampling_limit = DEFAULT; -SELECT @@global.optimizer_selectivity_sampling_limit = 5000; +SELECT @@global.optimizer_selectivity_sampling_limit = 100; SET @@session.optimizer_selectivity_sampling_limit = DEFAULT; -SELECT @@session.optimizer_selectivity_sampling_limit = 5000; +SELECT @@session.optimizer_selectivity_sampling_limit = 100; --echo '#--------------------FN_DYNVARS_115_03-------------------------#' diff --git a/sql/opt_range.h b/sql/opt_range.h index 963551cabdb..ddaa5c5e59a 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -1052,7 +1052,7 @@ void store_key_image_to_rec(Field *field, uchar *ptr, uint len); extern String null_string; /* check this number of rows (default value) */ -#define SELECTIVITY_SAMPLING_LIMIT 5000 +#define SELECTIVITY_SAMPLING_LIMIT 100 /* but no more then this part of table (10%) */ #define SELECTIVITY_SAMPLING_SHARE 0.10 /* do not check if we are going check less then this number of records */ From 09a1f410cb2e014156f9d6dee87798ab5b28042b Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sat, 20 Apr 2013 02:16:55 -0700 Subject: [PATCH 4/9] Fixed bug mdev-4406. This bug in the code of get_column_range_cardinality() could lead to wrong estimates of number of records in ranges for non-nullable columns. --- mysql-test/r/selectivity.result | 34 ++++++++++++++++++++++++++ mysql-test/r/selectivity_innodb.result | 34 ++++++++++++++++++++++++++ mysql-test/t/selectivity.test | 31 +++++++++++++++++++++++ sql/sql_statistics.cc | 2 +- 4 files changed, 100 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/selectivity.result b/mysql-test/r/selectivity.result index 512ef4ffc1b..e59f4310431 100644 --- a/mysql-test/r/selectivity.result +++ b/mysql-test/r/selectivity.result @@ -1094,4 +1094,38 @@ f1 f2 f2 set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; DROP TABLE t1,t2; set use_stat_tables=@save_use_stat_tables; +# +# Bug mdev-4406: range condition for non-nullable column +# when optimizer_use_condition_selectivity=3 +# +create table t1 (a int not null); +insert into t1 values +(7), (6), (4), (9), (1), (5), (2), (1), (3), (8); +set use_stat_tables='preferably'; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +flush table t1; +set optimizer_use_condition_selectivity=3; +select count(*) from t1 where a between 5 and 7; +count(*) +3 +explain extended select * from t1 where a between 5 and 7; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 10 25.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` between 5 and 7) +alter table t1 change column a a int; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +flush table t1; +explain extended select * from t1 where a between 5 and 7; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 10 25.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` between 5 and 7) +set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; +drop table t1; +set use_stat_tables=@save_use_stat_tables; set use_stat_tables=@save_use_stat_tables; diff --git a/mysql-test/r/selectivity_innodb.result b/mysql-test/r/selectivity_innodb.result index 2dce973a587..20efb16914b 100644 --- a/mysql-test/r/selectivity_innodb.result +++ b/mysql-test/r/selectivity_innodb.result @@ -1102,6 +1102,40 @@ f1 f2 f2 set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; DROP TABLE t1,t2; set use_stat_tables=@save_use_stat_tables; +# +# Bug mdev-4406: range condition for non-nullable column +# when optimizer_use_condition_selectivity=3 +# +create table t1 (a int not null); +insert into t1 values +(7), (6), (4), (9), (1), (5), (2), (1), (3), (8); +set use_stat_tables='preferably'; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +flush table t1; +set optimizer_use_condition_selectivity=3; +select count(*) from t1 where a between 5 and 7; +count(*) +3 +explain extended select * from t1 where a between 5 and 7; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 10 25.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` between 5 and 7) +alter table t1 change column a a int; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +flush table t1; +explain extended select * from t1 where a between 5 and 7; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 10 25.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` between 5 and 7) +set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; +drop table t1; +set use_stat_tables=@save_use_stat_tables; set use_stat_tables=@save_use_stat_tables; set optimizer_switch=@save_optimizer_switch_for_selectivity_test; SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/t/selectivity.test b/mysql-test/t/selectivity.test index 8bde4718fdd..47f62365816 100644 --- a/mysql-test/t/selectivity.test +++ b/mysql-test/t/selectivity.test @@ -676,5 +676,36 @@ DROP TABLE t1,t2; set use_stat_tables=@save_use_stat_tables; +--echo # +--echo # Bug mdev-4406: range condition for non-nullable column +--echo # when optimizer_use_condition_selectivity=3 +--echo # + +create table t1 (a int not null); +insert into t1 values + (7), (6), (4), (9), (1), (5), (2), (1), (3), (8); + +set use_stat_tables='preferably'; + +analyze table t1; +flush table t1; + +set optimizer_use_condition_selectivity=3; + +select count(*) from t1 where a between 5 and 7; +explain extended select * from t1 where a between 5 and 7; + +alter table t1 change column a a int; +analyze table t1; +flush table t1; + +explain extended select * from t1 where a between 5 and 7; + +set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; + +drop table t1; + +set use_stat_tables=@save_use_stat_tables; + set use_stat_tables=@save_use_stat_tables; diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 4df4b4d257d..f355f2c7760 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -3520,7 +3520,7 @@ double get_column_range_cardinality(Field *field, { double sel, min_mp_pos, max_mp_pos; - if (min_endp && !min_endp->key[0]) + if (min_endp && !(field->null_ptr && min_endp->key[0])) { store_key_image_to_rec(field, (uchar *) min_endp->key, min_endp->length); From 2e830cfbc81c545de135b4fbee751141741a11ab Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 20 Apr 2013 23:30:21 +0300 Subject: [PATCH 5/9] MDEV-4402 A function to visualize histograms data. --- mysql-test/r/statistics.result | 59 ++++++++++++++++++++++++++ mysql-test/t/statistics.test | 16 +++++++ sql/item_create.cc | 21 ++++++++++ sql/item_strfunc.cc | 77 ++++++++++++++++++++++++++++++++++ sql/item_strfunc.h | 16 +++++++ sql/sys_vars.cc | 3 +- 6 files changed, 190 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/statistics.result b/mysql-test/r/statistics.result index 20469c01a2e..4652420bd87 100644 --- a/mysql-test/r/statistics.result +++ b/mysql-test/r/statistics.result @@ -1416,6 +1416,65 @@ WORLD_INNODB CITY Country 1 17.5819 WORLD_INNODB COUNTRYLANGUAGE PRIMARY 1 4.2232 WORLD_INNODB COUNTRYLANGUAGE PRIMARY 2 1.0000 WORLD_INNODB COUNTRYLANGUAGE Percentage 1 2.7640 +set use_stat_tables='preferably'; +set histogram_size=100; +set histogram_type='SINGLE_PREC_HB'; +ANALYZE TABLE CountryLanguage; +set histogram_size=255; +set histogram_type='DOUBLE_PREC_HB'; +ANALYZE TABLE City; +select db_name,table_name,column_name,min_value,max_value,nulls_ratio,avg_length,avg_frequency,hist_size,hist_type,hex(histogram),decode_histogram(histogram,hist_type) from mysql.column_stats where table_name='CountryLanguage' and column_name = 'Percentage';; +db_name world +table_name CountryLanguage +column_name Percentage +min_value 0.0 +max_value 99.9 +nulls_ratio 0.0000 +avg_length 4.0000 +avg_frequency 2.7640 +hist_size 0 +hist_type NULL +hex(histogram) NULL +decode_histogram(histogram,hist_type) NULL +db_name world_innodb +table_name CountryLanguage +column_name Percentage +min_value 0.0 +max_value 99.9 +nulls_ratio 0.0000 +avg_length 4.0000 +avg_frequency 2.7640 +hist_size 100 +hist_type SINGLE_PREC_HB +hex(histogram) 0000000000000000000000000101010101010101010202020303030304040404050505050606070707080809090A0A0B0C0D0D0E0E0F10111213131415161718191B1C1E202224292A2E33373B4850575F6A76818C9AA7B9C4CFDADFE5EBF0F4F8FAFCFF +decode_histogram(histogram,hist_type) 0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.004,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.004,0.000,0.000,0.004,0.000,0.000,0.000,0.004,0.000,0.000,0.000,0.004,0.000,0.000,0.000,0.004,0.000,0.004,0.000,0.000,0.004,0.000,0.004,0.000,0.004,0.000,0.004,0.004,0.004,0.000,0.004,0.000,0.004,0.004,0.004,0.004,0.004,0.000,0.004,0.004,0.004,0.004,0.004,0.004,0.008,0.004,0.008,0.008,0.008,0.008,0.020,0.004,0.016,0.020,0.016,0.016,0.051,0.031,0.027,0.031,0.043,0.047,0.043,0.043,0.055,0.051,0.071,0.043,0.043,0.043,0.020,0.024,0.024,0.020,0.016,0.016,0.008,0.008,0.012 +select db_name,table_name,column_name,min_value,max_value,nulls_ratio,avg_length,avg_frequency,hist_size,hist_type,hex(histogram),decode_histogram(histogram,hist_type) from mysql.column_stats where table_name='City' and column_name = 'Population';; +db_name world +table_name City +column_name Population +min_value 42 +max_value 10500000 +nulls_ratio 0.0000 +avg_length 4.0000 +avg_frequency 1.0467 +hist_size 0 +hist_type NULL +hex(histogram) NULL +decode_histogram(histogram,hist_type) NULL +db_name world_innodb +table_name City +column_name Population +min_value 42 +max_value 10500000 +nulls_ratio 0.0000 +avg_length 4.0000 +avg_frequency 1.0467 +hist_size 255 +hist_type DOUBLE_PREC_HB +hex(histogram) 1F00A1002B023002350238023F02430249024E02520258025D02630268026E02720276027B02800285028C02920297029D02A102A802AC02B402BC02C402CC02D302DA02E302EA02F102F802010305030C03120319031F03290333033D0343034F03590363036D037803840390039A03A603B303C303D103E003F203020412042404330440045304600472047F049104A204B804C804DE04F2040A0526053F0558056F058E05B305D905F4051306380667068406AB06DA06020731075C079407C507F8072E085E08A508DF0824096909CC092E0A760AD50A400BA90B150CAD0C310D240E130F0E103B11B9126B14F0166B192F1CB71FFF240630483FC567A5 +decode_histogram(histogram,hist_type) 0.00047,0.00198,0.00601,0.00008,0.00008,0.00005,0.00011,0.00006,0.00009,0.00008,0.00006,0.00009,0.00008,0.00009,0.00008,0.00009,0.00006,0.00006,0.00008,0.00008,0.00008,0.00011,0.00009,0.00008,0.00009,0.00006,0.00011,0.00006,0.00012,0.00012,0.00012,0.00012,0.00011,0.00011,0.00014,0.00011,0.00011,0.00011,0.00014,0.00006,0.00011,0.00009,0.00011,0.00009,0.00015,0.00015,0.00015,0.00009,0.00018,0.00015,0.00015,0.00015,0.00017,0.00018,0.00018,0.00015,0.00018,0.00020,0.00024,0.00021,0.00023,0.00027,0.00024,0.00024,0.00027,0.00023,0.00020,0.00029,0.00020,0.00027,0.00020,0.00027,0.00026,0.00034,0.00024,0.00034,0.00031,0.00037,0.00043,0.00038,0.00038,0.00035,0.00047,0.00056,0.00058,0.00041,0.00047,0.00056,0.00072,0.00044,0.00060,0.00072,0.00061,0.00072,0.00066,0.00085,0.00075,0.00078,0.00082,0.00073,0.00108,0.00089,0.00105,0.00105,0.00151,0.00150,0.00110,0.00145,0.00163,0.00160,0.00165,0.00232,0.00201,0.00371,0.00365,0.00383,0.00459,0.00583,0.00662,0.00984,0.00969,0.01080,0.01379,0.02063,0.04308,0.05960,0.15816 +set histogram_type=default; +set histogram_size=default; use test; DROP DATABASE world; SELECT UPPER(db_name), UPPER(table_name), cardinality diff --git a/mysql-test/t/statistics.test b/mysql-test/t/statistics.test index b2a052fd3e8..e2ba9d4e173 100644 --- a/mysql-test/t/statistics.test +++ b/mysql-test/t/statistics.test @@ -564,6 +564,22 @@ SELECT UPPER(db_name), UPPER(table_name), index_name, prefix_arity, avg_frequency FROM mysql.index_stats; +set use_stat_tables='preferably'; +--disable_result_log +set histogram_size=100; +set histogram_type='SINGLE_PREC_HB'; +ANALYZE TABLE CountryLanguage; +set histogram_size=255; +set histogram_type='DOUBLE_PREC_HB'; +ANALYZE TABLE City; +--enable_result_log + +--query_vertical select db_name,table_name,column_name,min_value,max_value,nulls_ratio,avg_length,avg_frequency,hist_size,hist_type,hex(histogram),decode_histogram(histogram,hist_type) from mysql.column_stats where table_name='CountryLanguage' and column_name = 'Percentage'; +--query_vertical select db_name,table_name,column_name,min_value,max_value,nulls_ratio,avg_length,avg_frequency,hist_size,hist_type,hex(histogram),decode_histogram(histogram,hist_type) from mysql.column_stats where table_name='City' and column_name = 'Population'; + +set histogram_type=default; +set histogram_size=default; + use test; DROP DATABASE world; diff --git a/sql/item_create.cc b/sql/item_create.cc index c1cefed6f8b..ce4dc7ced8f 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -614,6 +614,19 @@ protected: }; +class Create_func_decode_histogram : public Create_func_arg2 +{ +public: + Item *create_2_arg(THD *thd, Item *arg1, Item *arg2); + + static Create_func_decode_histogram s_singleton; + +protected: + Create_func_decode_histogram() {} + virtual ~Create_func_decode_histogram() {} +}; + + class Create_func_concat_ws : public Create_native_func { public: @@ -3231,6 +3244,13 @@ Create_func_concat::create_native(THD *thd, LEX_STRING name, return new (thd->mem_root) Item_func_concat(*item_list); } +Create_func_decode_histogram Create_func_decode_histogram::s_singleton; + +Item * +Create_func_decode_histogram::create_2_arg(THD *thd, Item *arg1, Item *arg2) +{ + return new (thd->mem_root) Item_func_decode_histogram(arg1, arg2); +} Create_func_concat_ws Create_func_concat_ws::s_singleton; @@ -5377,6 +5397,7 @@ static Native_func_registry func_array[] = { { C_STRING_WITH_LEN("DAYOFYEAR") }, BUILDER(Create_func_dayofyear)}, { { C_STRING_WITH_LEN("DECODE") }, BUILDER(Create_func_decode)}, { { C_STRING_WITH_LEN("DEGREES") }, BUILDER(Create_func_degrees)}, + { { C_STRING_WITH_LEN("DECODE_HISTOGRAM") }, BUILDER(Create_func_decode_histogram)}, { { C_STRING_WITH_LEN("DES_DECRYPT") }, BUILDER(Create_func_des_decrypt)}, { { C_STRING_WITH_LEN("DES_ENCRYPT") }, BUILDER(Create_func_des_encrypt)}, { { C_STRING_WITH_LEN("DIMENSION") }, GEOM_BUILDER(Create_func_dimension)}, diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 93569082d74..5cce910758a 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -60,6 +60,7 @@ C_MODE_START C_MODE_END #include "sql_show.h" // append_identifier #include +#include "sql_statistics.h" /** @todo Remove this. It is not safe to use a shared String object. @@ -472,6 +473,82 @@ void Item_func_aes_decrypt::fix_length_and_dec() set_persist_maybe_null(1); } +/////////////////////////////////////////////////////////////////////////////// + + +const char *histogram_types[] = + {"SINGLE_PREC_HB", "DOUBLE_PREC_HB", 0}; +static TYPELIB hystorgam_types_typelib= + { array_elements(histogram_types), + "histogram_types", + histogram_types, NULL}; +const char *representation_by_type[]= {"%.3f", "%.5f"}; + +String *Item_func_decode_histogram::val_str(String *str) +{ + DBUG_ASSERT(fixed == 1); + char buff[STRING_BUFFER_USUAL_SIZE]; + String *res, tmp(buff, sizeof(buff), &my_charset_bin); + int type; + + tmp.length(0); + if (!(res= args[1]->val_str(&tmp)) || + (type= find_type(res->c_ptr_safe(), + &hystorgam_types_typelib, MYF(0))) <= 0) + { + null_value= 1; + return 0; + } + type--; + + tmp.length(0); + if (!(res= args[0]->val_str(&tmp))) + { + null_value= 1; + return 0; + } + if (type == DOUBLE_PREC_HB && res->length() % 2 != 0) + res->length(res->length() - 1); // one byte is unused + + double prev= 0.0; + uint i; + str->length(0); + bool first= true; + const uchar *p= (uchar*)res->c_ptr(); + for (i= 0; i < res->length(); i++) + { + char numbuf[32]; + double val; + switch (type) + { + case SINGLE_PREC_HB: + val= p[i] / ((double)((1 << 8) - 1)); + break; + case DOUBLE_PREC_HB: + val= ((uint16 *)(p + i))[0] / ((double)((1 << 16) - 1)); + i++; + break; + default: + val= 0; + DBUG_ASSERT(0); + } + /* show delta with previous value */ + int size= my_snprintf(numbuf, sizeof(numbuf), + representation_by_type[type], val - prev); + if (first) + first= false; + else + str->append(","); + str->append(numbuf, size); + prev= val; + } + + null_value=0; + return str; +} + + +/////////////////////////////////////////////////////////////////////////////// /** Concatenate args with the following premises: diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 89d7fa67f6b..169da25e826 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -143,6 +143,22 @@ public: const char *func_name() const { return "concat"; } }; +class Item_func_decode_histogram :public Item_str_func +{ + String tmp_value; +public: + Item_func_decode_histogram(Item *a, Item *b) + :Item_str_func(a, b) {} + String *val_str(String *); + void fix_length_and_dec() + { + collation.set(system_charset_info); + max_length= MAX_BLOB_WIDTH; + set_persist_maybe_null(1); + } + const char *func_name() const { return "decode_histogram"; } +}; + class Item_func_concat_ws :public Item_str_func { String tmp_value; diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 24009cb5a99..e51fd1cc11c 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -3970,8 +3970,7 @@ static Sys_var_ulong Sys_histogram_size( SESSION_VAR(histogram_size), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 255), DEFAULT(0), BLOCK_SIZE(1)); -const char *histogram_types[] = - {"SINGLE_PREC_HB", "DOUBLE_PREC_HB", 0}; +extern const char *histogram_types[]; static Sys_var_enum Sys_histogram_type( "histogram_type", "Specifies type of the histograms created by ANALYZE. " From c0034df25ee1d96c6b544199863a27d2cdd08310 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sat, 20 Apr 2013 18:18:01 -0700 Subject: [PATCH 6/9] Changed a test case. --- mysql-test/r/statistics.result | 6 +++--- mysql-test/t/statistics.test | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/statistics.result b/mysql-test/r/statistics.result index 4652420bd87..a7543cd9117 100644 --- a/mysql-test/r/statistics.result +++ b/mysql-test/r/statistics.result @@ -1420,7 +1420,7 @@ set use_stat_tables='preferably'; set histogram_size=100; set histogram_type='SINGLE_PREC_HB'; ANALYZE TABLE CountryLanguage; -set histogram_size=255; +set histogram_size=254; set histogram_type='DOUBLE_PREC_HB'; ANALYZE TABLE City; select db_name,table_name,column_name,min_value,max_value,nulls_ratio,avg_length,avg_frequency,hist_size,hist_type,hex(histogram),decode_histogram(histogram,hist_type) from mysql.column_stats where table_name='CountryLanguage' and column_name = 'Percentage';; @@ -1469,9 +1469,9 @@ max_value 10500000 nulls_ratio 0.0000 avg_length 4.0000 avg_frequency 1.0467 -hist_size 255 +hist_size 254 hist_type DOUBLE_PREC_HB -hex(histogram) 1F00A1002B023002350238023F02430249024E02520258025D02630268026E02720276027B02800285028C02920297029D02A102A802AC02B402BC02C402CC02D302DA02E302EA02F102F802010305030C03120319031F03290333033D0343034F03590363036D037803840390039A03A603B303C303D103E003F203020412042404330440045304600472047F049104A204B804C804DE04F2040A0526053F0558056F058E05B305D905F4051306380667068406AB06DA06020731075C079407C507F8072E085E08A508DF0824096909CC092E0A760AD50A400BA90B150CAD0C310D240E130F0E103B11B9126B14F0166B192F1CB71FFF240630483FC567A5 +hex(histogram) 1F00A1002B023002350238023F02430249024E02520258025D02630268026E02720276027B02800285028C02920297029D02A102A802AC02B402BC02C402CC02D302DA02E302EA02F102F802010305030C03120319031F03290333033D0343034F03590363036D037803840390039A03A603B303C303D103E003F203020412042404330440045304600472047F049104A204B804C804DE04F2040A0526053F0558056F058E05B305D905F4051306380667068406AB06DA06020731075C079407C507F8072E085E08A508DF0824096909CC092E0A760AD50A400BA90B150CAD0C310D240E130F0E103B11B9126B14F0166B192F1CB71FFF240630483FC567 decode_histogram(histogram,hist_type) 0.00047,0.00198,0.00601,0.00008,0.00008,0.00005,0.00011,0.00006,0.00009,0.00008,0.00006,0.00009,0.00008,0.00009,0.00008,0.00009,0.00006,0.00006,0.00008,0.00008,0.00008,0.00011,0.00009,0.00008,0.00009,0.00006,0.00011,0.00006,0.00012,0.00012,0.00012,0.00012,0.00011,0.00011,0.00014,0.00011,0.00011,0.00011,0.00014,0.00006,0.00011,0.00009,0.00011,0.00009,0.00015,0.00015,0.00015,0.00009,0.00018,0.00015,0.00015,0.00015,0.00017,0.00018,0.00018,0.00015,0.00018,0.00020,0.00024,0.00021,0.00023,0.00027,0.00024,0.00024,0.00027,0.00023,0.00020,0.00029,0.00020,0.00027,0.00020,0.00027,0.00026,0.00034,0.00024,0.00034,0.00031,0.00037,0.00043,0.00038,0.00038,0.00035,0.00047,0.00056,0.00058,0.00041,0.00047,0.00056,0.00072,0.00044,0.00060,0.00072,0.00061,0.00072,0.00066,0.00085,0.00075,0.00078,0.00082,0.00073,0.00108,0.00089,0.00105,0.00105,0.00151,0.00150,0.00110,0.00145,0.00163,0.00160,0.00165,0.00232,0.00201,0.00371,0.00365,0.00383,0.00459,0.00583,0.00662,0.00984,0.00969,0.01080,0.01379,0.02063,0.04308,0.05960,0.15816 set histogram_type=default; set histogram_size=default; diff --git a/mysql-test/t/statistics.test b/mysql-test/t/statistics.test index e2ba9d4e173..97db984d4c8 100644 --- a/mysql-test/t/statistics.test +++ b/mysql-test/t/statistics.test @@ -569,7 +569,7 @@ set use_stat_tables='preferably'; set histogram_size=100; set histogram_type='SINGLE_PREC_HB'; ANALYZE TABLE CountryLanguage; -set histogram_size=255; +set histogram_size=254; set histogram_type='DOUBLE_PREC_HB'; ANALYZE TABLE City; --enable_result_log From 3fccd933dd7e1555290de3f432911a05320f1153 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 21 Apr 2013 21:39:01 +0300 Subject: [PATCH 7/9] Fix of the test suite. --- mysql-test/r/statistics.result | 1 + mysql-test/t/statistics.test | 1 + 2 files changed, 2 insertions(+) diff --git a/mysql-test/r/statistics.result b/mysql-test/r/statistics.result index a7543cd9117..6c00f7a5299 100644 --- a/mysql-test/r/statistics.result +++ b/mysql-test/r/statistics.result @@ -1423,6 +1423,7 @@ ANALYZE TABLE CountryLanguage; set histogram_size=254; set histogram_type='DOUBLE_PREC_HB'; ANALYZE TABLE City; +FLUSH TABLES; select db_name,table_name,column_name,min_value,max_value,nulls_ratio,avg_length,avg_frequency,hist_size,hist_type,hex(histogram),decode_histogram(histogram,hist_type) from mysql.column_stats where table_name='CountryLanguage' and column_name = 'Percentage';; db_name world table_name CountryLanguage diff --git a/mysql-test/t/statistics.test b/mysql-test/t/statistics.test index 97db984d4c8..ee44d1ed228 100644 --- a/mysql-test/t/statistics.test +++ b/mysql-test/t/statistics.test @@ -572,6 +572,7 @@ ANALYZE TABLE CountryLanguage; set histogram_size=254; set histogram_type='DOUBLE_PREC_HB'; ANALYZE TABLE City; +FLUSH TABLES; --enable_result_log --query_vertical select db_name,table_name,column_name,min_value,max_value,nulls_ratio,avg_length,avg_frequency,hist_size,hist_type,hex(histogram),decode_histogram(histogram,hist_type) from mysql.column_stats where table_name='CountryLanguage' and column_name = 'Percentage'; From 30e66dd6e75acc55ef2a64e7632e18c516725af4 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 21 Apr 2013 22:12:57 +0300 Subject: [PATCH 8/9] decode_histogram fixed to show delta of the last value with maximum. --- mysql-test/r/statistics.result | 4 ++-- sql/item_strfunc.cc | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/statistics.result b/mysql-test/r/statistics.result index 6c00f7a5299..a60842d0716 100644 --- a/mysql-test/r/statistics.result +++ b/mysql-test/r/statistics.result @@ -1448,7 +1448,7 @@ avg_frequency 2.7640 hist_size 100 hist_type SINGLE_PREC_HB hex(histogram) 0000000000000000000000000101010101010101010202020303030304040404050505050606070707080809090A0A0B0C0D0D0E0E0F10111213131415161718191B1C1E202224292A2E33373B4850575F6A76818C9AA7B9C4CFDADFE5EBF0F4F8FAFCFF -decode_histogram(histogram,hist_type) 0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.004,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.004,0.000,0.000,0.004,0.000,0.000,0.000,0.004,0.000,0.000,0.000,0.004,0.000,0.000,0.000,0.004,0.000,0.004,0.000,0.000,0.004,0.000,0.004,0.000,0.004,0.000,0.004,0.004,0.004,0.000,0.004,0.000,0.004,0.004,0.004,0.004,0.004,0.000,0.004,0.004,0.004,0.004,0.004,0.004,0.008,0.004,0.008,0.008,0.008,0.008,0.020,0.004,0.016,0.020,0.016,0.016,0.051,0.031,0.027,0.031,0.043,0.047,0.043,0.043,0.055,0.051,0.071,0.043,0.043,0.043,0.020,0.024,0.024,0.020,0.016,0.016,0.008,0.008,0.012 +decode_histogram(histogram,hist_type) 0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.004,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.004,0.000,0.000,0.004,0.000,0.000,0.000,0.004,0.000,0.000,0.000,0.004,0.000,0.000,0.000,0.004,0.000,0.004,0.000,0.000,0.004,0.000,0.004,0.000,0.004,0.000,0.004,0.004,0.004,0.000,0.004,0.000,0.004,0.004,0.004,0.004,0.004,0.000,0.004,0.004,0.004,0.004,0.004,0.004,0.008,0.004,0.008,0.008,0.008,0.008,0.020,0.004,0.016,0.020,0.016,0.016,0.051,0.031,0.027,0.031,0.043,0.047,0.043,0.043,0.055,0.051,0.071,0.043,0.043,0.043,0.020,0.024,0.024,0.020,0.016,0.016,0.008,0.008,0.012,0.000 select db_name,table_name,column_name,min_value,max_value,nulls_ratio,avg_length,avg_frequency,hist_size,hist_type,hex(histogram),decode_histogram(histogram,hist_type) from mysql.column_stats where table_name='City' and column_name = 'Population';; db_name world table_name City @@ -1473,7 +1473,7 @@ avg_frequency 1.0467 hist_size 254 hist_type DOUBLE_PREC_HB hex(histogram) 1F00A1002B023002350238023F02430249024E02520258025D02630268026E02720276027B02800285028C02920297029D02A102A802AC02B402BC02C402CC02D302DA02E302EA02F102F802010305030C03120319031F03290333033D0343034F03590363036D037803840390039A03A603B303C303D103E003F203020412042404330440045304600472047F049104A204B804C804DE04F2040A0526053F0558056F058E05B305D905F4051306380667068406AB06DA06020731075C079407C507F8072E085E08A508DF0824096909CC092E0A760AD50A400BA90B150CAD0C310D240E130F0E103B11B9126B14F0166B192F1CB71FFF240630483FC567 -decode_histogram(histogram,hist_type) 0.00047,0.00198,0.00601,0.00008,0.00008,0.00005,0.00011,0.00006,0.00009,0.00008,0.00006,0.00009,0.00008,0.00009,0.00008,0.00009,0.00006,0.00006,0.00008,0.00008,0.00008,0.00011,0.00009,0.00008,0.00009,0.00006,0.00011,0.00006,0.00012,0.00012,0.00012,0.00012,0.00011,0.00011,0.00014,0.00011,0.00011,0.00011,0.00014,0.00006,0.00011,0.00009,0.00011,0.00009,0.00015,0.00015,0.00015,0.00009,0.00018,0.00015,0.00015,0.00015,0.00017,0.00018,0.00018,0.00015,0.00018,0.00020,0.00024,0.00021,0.00023,0.00027,0.00024,0.00024,0.00027,0.00023,0.00020,0.00029,0.00020,0.00027,0.00020,0.00027,0.00026,0.00034,0.00024,0.00034,0.00031,0.00037,0.00043,0.00038,0.00038,0.00035,0.00047,0.00056,0.00058,0.00041,0.00047,0.00056,0.00072,0.00044,0.00060,0.00072,0.00061,0.00072,0.00066,0.00085,0.00075,0.00078,0.00082,0.00073,0.00108,0.00089,0.00105,0.00105,0.00151,0.00150,0.00110,0.00145,0.00163,0.00160,0.00165,0.00232,0.00201,0.00371,0.00365,0.00383,0.00459,0.00583,0.00662,0.00984,0.00969,0.01080,0.01379,0.02063,0.04308,0.05960,0.15816 +decode_histogram(histogram,hist_type) 0.00047,0.00198,0.00601,0.00008,0.00008,0.00005,0.00011,0.00006,0.00009,0.00008,0.00006,0.00009,0.00008,0.00009,0.00008,0.00009,0.00006,0.00006,0.00008,0.00008,0.00008,0.00011,0.00009,0.00008,0.00009,0.00006,0.00011,0.00006,0.00012,0.00012,0.00012,0.00012,0.00011,0.00011,0.00014,0.00011,0.00011,0.00011,0.00014,0.00006,0.00011,0.00009,0.00011,0.00009,0.00015,0.00015,0.00015,0.00009,0.00018,0.00015,0.00015,0.00015,0.00017,0.00018,0.00018,0.00015,0.00018,0.00020,0.00024,0.00021,0.00023,0.00027,0.00024,0.00024,0.00027,0.00023,0.00020,0.00029,0.00020,0.00027,0.00020,0.00027,0.00026,0.00034,0.00024,0.00034,0.00031,0.00037,0.00043,0.00038,0.00038,0.00035,0.00047,0.00056,0.00058,0.00041,0.00047,0.00056,0.00072,0.00044,0.00060,0.00072,0.00061,0.00072,0.00066,0.00085,0.00075,0.00078,0.00082,0.00073,0.00108,0.00089,0.00105,0.00105,0.00151,0.00150,0.00110,0.00145,0.00163,0.00160,0.00165,0.00232,0.00201,0.00371,0.00365,0.00383,0.00459,0.00583,0.00662,0.00984,0.00969,0.01080,0.01379,0.02063,0.04308,0.05960,0.15816,0.59464 set histogram_type=default; set histogram_size=default; use test; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 5cce910758a..1ee4a4436fe 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -513,11 +513,10 @@ String *Item_func_decode_histogram::val_str(String *str) double prev= 0.0; uint i; str->length(0); - bool first= true; + char numbuf[32]; const uchar *p= (uchar*)res->c_ptr(); for (i= 0; i < res->length(); i++) { - char numbuf[32]; double val; switch (type) { @@ -535,13 +534,14 @@ String *Item_func_decode_histogram::val_str(String *str) /* show delta with previous value */ int size= my_snprintf(numbuf, sizeof(numbuf), representation_by_type[type], val - prev); - if (first) - first= false; - else - str->append(","); str->append(numbuf, size); + str->append(","); prev= val; } + /* show delta with max */ + int size= my_snprintf(numbuf, sizeof(numbuf), + representation_by_type[type], 1.0 - prev); + str->append(numbuf, size); null_value=0; return str; From c076f7302b5373e18b6ce66d0f8711cd4ebaf36d Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 22 Apr 2013 06:46:26 +0300 Subject: [PATCH 9/9] Removed comparison of table names. --- mysql-test/r/statistics.result | 28 ++++++++++++++++++++++++++-- mysql-test/t/statistics.test | 4 ++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/statistics.result b/mysql-test/r/statistics.result index a60842d0716..75d4e8f00b2 100644 --- a/mysql-test/r/statistics.result +++ b/mysql-test/r/statistics.result @@ -1424,7 +1424,7 @@ set histogram_size=254; set histogram_type='DOUBLE_PREC_HB'; ANALYZE TABLE City; FLUSH TABLES; -select db_name,table_name,column_name,min_value,max_value,nulls_ratio,avg_length,avg_frequency,hist_size,hist_type,hex(histogram),decode_histogram(histogram,hist_type) from mysql.column_stats where table_name='CountryLanguage' and column_name = 'Percentage';; +select db_name,table_name,column_name,min_value,max_value,nulls_ratio,avg_length,avg_frequency,hist_size,hist_type,hex(histogram),decode_histogram(histogram,hist_type) from mysql.column_stats where column_name = 'Percentage';; db_name world table_name CountryLanguage column_name Percentage @@ -1449,7 +1449,19 @@ hist_size 100 hist_type SINGLE_PREC_HB hex(histogram) 0000000000000000000000000101010101010101010202020303030304040404050505050606070707080809090A0A0B0C0D0D0E0E0F10111213131415161718191B1C1E202224292A2E33373B4850575F6A76818C9AA7B9C4CFDADFE5EBF0F4F8FAFCFF decode_histogram(histogram,hist_type) 0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.004,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.000,0.004,0.000,0.000,0.004,0.000,0.000,0.000,0.004,0.000,0.000,0.000,0.004,0.000,0.000,0.000,0.004,0.000,0.004,0.000,0.000,0.004,0.000,0.004,0.000,0.004,0.000,0.004,0.004,0.004,0.000,0.004,0.000,0.004,0.004,0.004,0.004,0.004,0.000,0.004,0.004,0.004,0.004,0.004,0.004,0.008,0.004,0.008,0.008,0.008,0.008,0.020,0.004,0.016,0.020,0.016,0.016,0.051,0.031,0.027,0.031,0.043,0.047,0.043,0.043,0.055,0.051,0.071,0.043,0.043,0.043,0.020,0.024,0.024,0.020,0.016,0.016,0.008,0.008,0.012,0.000 -select db_name,table_name,column_name,min_value,max_value,nulls_ratio,avg_length,avg_frequency,hist_size,hist_type,hex(histogram),decode_histogram(histogram,hist_type) from mysql.column_stats where table_name='City' and column_name = 'Population';; +select db_name,table_name,column_name,min_value,max_value,nulls_ratio,avg_length,avg_frequency,hist_size,hist_type,hex(histogram),decode_histogram(histogram,hist_type) from mysql.column_stats where column_name = 'Population';; +db_name world +table_name Country +column_name Population +min_value 0 +max_value 1277558000 +nulls_ratio 0.0000 +avg_length 4.0000 +avg_frequency 1.0575 +hist_size 0 +hist_type NULL +hex(histogram) NULL +decode_histogram(histogram,hist_type) NULL db_name world table_name City column_name Population @@ -1463,6 +1475,18 @@ hist_type NULL hex(histogram) NULL decode_histogram(histogram,hist_type) NULL db_name world_innodb +table_name Country +column_name Population +min_value 0 +max_value 1277558000 +nulls_ratio 0.0000 +avg_length 4.0000 +avg_frequency 1.0575 +hist_size 0 +hist_type NULL +hex(histogram) NULL +decode_histogram(histogram,hist_type) NULL +db_name world_innodb table_name City column_name Population min_value 42 diff --git a/mysql-test/t/statistics.test b/mysql-test/t/statistics.test index ee44d1ed228..f7a6c1757cb 100644 --- a/mysql-test/t/statistics.test +++ b/mysql-test/t/statistics.test @@ -575,8 +575,8 @@ ANALYZE TABLE City; FLUSH TABLES; --enable_result_log ---query_vertical select db_name,table_name,column_name,min_value,max_value,nulls_ratio,avg_length,avg_frequency,hist_size,hist_type,hex(histogram),decode_histogram(histogram,hist_type) from mysql.column_stats where table_name='CountryLanguage' and column_name = 'Percentage'; ---query_vertical select db_name,table_name,column_name,min_value,max_value,nulls_ratio,avg_length,avg_frequency,hist_size,hist_type,hex(histogram),decode_histogram(histogram,hist_type) from mysql.column_stats where table_name='City' and column_name = 'Population'; +--query_vertical select db_name,table_name,column_name,min_value,max_value,nulls_ratio,avg_length,avg_frequency,hist_size,hist_type,hex(histogram),decode_histogram(histogram,hist_type) from mysql.column_stats where column_name = 'Percentage'; +--query_vertical select db_name,table_name,column_name,min_value,max_value,nulls_ratio,avg_length,avg_frequency,hist_size,hist_type,hex(histogram),decode_histogram(histogram,hist_type) from mysql.column_stats where column_name = 'Population'; set histogram_type=default; set histogram_size=default;