diff options
-rw-r--r-- | mysql-test/r/selectivity.result | 341 | ||||
-rw-r--r-- | mysql-test/r/selectivity_innodb.result | 341 | ||||
-rw-r--r-- | mysql-test/t/selectivity.test | 117 | ||||
-rw-r--r-- | sql/sql_select.cc | 102 | ||||
-rw-r--r-- | sql/sql_statistics.cc | 44 | ||||
-rw-r--r-- | sql/table.cc | 6 |
6 files changed, 914 insertions, 37 deletions
diff --git a/mysql-test/r/selectivity.result b/mysql-test/r/selectivity.result index af3f6fdda2d..77a26bc21f1 100644 --- a/mysql-test/r/selectivity.result +++ b/mysql-test/r/selectivity.result @@ -11,6 +11,347 @@ CREATE DATABASE dbt3_s001; use dbt3_s001; set @save_optimizer_use_condition_selectivity=@@optimizer_use_condition_selectivity; set @save_histogram_size=@@histogram_size; +=== Q15 === +create view revenue0 (supplier_no, total_revenue) as +select l_suppkey, sum(l_extendedprice * (1 - l_discount)) +from lineitem +where +l_shipdate >= '1995-08-01' + and l_shipdate < date_add('1995-08-01', interval 90 day) +group by l_suppkey; +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='index_condition_pushdown=off'; +set optimizer_use_condition_selectivity=1; +EXPLAIN EXTENDED select s_suppkey, s_name, s_address, s_phone, total_revenue +from supplier, revenue0 +where s_suppkey = supplier_no +and total_revenue = (select max(total_revenue) from revenue0) +order by s_suppkey; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY supplier ALL PRIMARY NULL NULL NULL 10 100.00 Using filesort +1 PRIMARY <derived3> ref key0 key0 5 dbt3_s001.supplier.s_suppkey 10 100.00 Using where +3 DERIVED lineitem range i_l_shipdate i_l_shipdate 4 NULL 268 100.00 Using where; Using temporary; Using filesort +2 SUBQUERY <derived4> ALL NULL NULL NULL NULL 268 100.00 +4 DERIVED lineitem range i_l_shipdate i_l_shipdate 4 NULL 268 100.00 Using where; Using temporary; Using filesort +Warnings: +Note 1003 select `dbt3_s001`.`supplier`.`s_suppkey` AS `s_suppkey`,`dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`supplier`.`s_address` AS `s_address`,`dbt3_s001`.`supplier`.`s_phone` AS `s_phone`,`revenue0`.`total_revenue` AS `total_revenue` from `dbt3_s001`.`supplier` join `dbt3_s001`.`revenue0` where ((`revenue0`.`supplier_no` = `dbt3_s001`.`supplier`.`s_suppkey`) and (`revenue0`.`total_revenue` = (select max(`revenue0`.`total_revenue`) from `dbt3_s001`.`revenue0`))) order by `dbt3_s001`.`supplier`.`s_suppkey` +select s_suppkey, s_name, s_address, s_phone, total_revenue +from supplier, revenue0 +where s_suppkey = supplier_no +and total_revenue = (select max(total_revenue) from revenue0) +order by s_suppkey; +s_suppkey s_name s_address s_phone total_revenue +1 Supplier#000000001 N kD4on9OM Ipw3,gf0JBoQDd7tgrzrddZ 27-918-335-1736 729084.7773 +set optimizer_use_condition_selectivity=3; +EXPLAIN EXTENDED select s_suppkey, s_name, s_address, s_phone, total_revenue +from supplier, revenue0 +where s_suppkey = supplier_no +and total_revenue = (select max(total_revenue) from revenue0) +order by s_suppkey; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY supplier ALL PRIMARY NULL NULL NULL 10 100.00 Using filesort +1 PRIMARY <derived3> ref key0 key0 5 dbt3_s001.supplier.s_suppkey 10 100.00 Using where +3 DERIVED lineitem range i_l_shipdate i_l_shipdate 4 NULL 268 0.20 Using where; Using temporary; Using filesort +2 SUBQUERY <derived4> ALL NULL NULL NULL NULL 268 100.00 +4 DERIVED lineitem range i_l_shipdate i_l_shipdate 4 NULL 268 0.20 Using where; Using temporary; Using filesort +Warnings: +Note 1003 select `dbt3_s001`.`supplier`.`s_suppkey` AS `s_suppkey`,`dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`supplier`.`s_address` AS `s_address`,`dbt3_s001`.`supplier`.`s_phone` AS `s_phone`,`revenue0`.`total_revenue` AS `total_revenue` from `dbt3_s001`.`supplier` join `dbt3_s001`.`revenue0` where ((`revenue0`.`supplier_no` = `dbt3_s001`.`supplier`.`s_suppkey`) and (`revenue0`.`total_revenue` = (select max(`revenue0`.`total_revenue`) from `dbt3_s001`.`revenue0`))) order by `dbt3_s001`.`supplier`.`s_suppkey` +select s_suppkey, s_name, s_address, s_phone, total_revenue +from supplier, revenue0 +where s_suppkey = supplier_no +and total_revenue = (select max(total_revenue) from revenue0) +order by s_suppkey; +s_suppkey s_name s_address s_phone total_revenue +1 Supplier#000000001 N kD4on9OM Ipw3,gf0JBoQDd7tgrzrddZ 27-918-335-1736 729084.7773 +set optimizer_switch=@save_optimizer_switch; +drop view revenue0; +=== Q16 === +set optimizer_use_condition_selectivity=1; +EXPLAIN EXTENDED select p_brand, p_type, p_size, count(distinct ps_suppkey) as supplier_cnt +from partsupp, part +where p_partkey = ps_partkey +and p_brand <> 'Brand#11' + and p_type not like 'SMALL POLISHED%' + and p_size in (49, 37, 27, 5, 40, 6, 22, 8) +and ps_suppkey not in (select s_suppkey from supplier +where s_comment like '%Customer%Complaints%') +group by p_brand, p_type, p_size +order by supplier_cnt desc, p_brand, p_type, p_size; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 100.00 Using where; Using temporary; Using filesort +1 PRIMARY partsupp ref PRIMARY,i_ps_partkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 Using where; Using index +2 MATERIALIZED supplier ALL PRIMARY NULL NULL NULL 10 100.00 Using where +Warnings: +Note 1003 select `dbt3_s001`.`part`.`p_brand` AS `p_brand`,`dbt3_s001`.`part`.`p_type` AS `p_type`,`dbt3_s001`.`part`.`p_size` AS `p_size`,count(distinct `dbt3_s001`.`partsupp`.`ps_suppkey`) AS `supplier_cnt` from `dbt3_s001`.`partsupp` join `dbt3_s001`.`part` where ((`dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey`) and (`dbt3_s001`.`part`.`p_brand` <> 'Brand#11') and (not((`dbt3_s001`.`part`.`p_type` like 'SMALL POLISHED%'))) and (`dbt3_s001`.`part`.`p_size` in (49,37,27,5,40,6,22,8)) and (not(<expr_cache><`dbt3_s001`.`partsupp`.`ps_suppkey`>(<in_optimizer>(`dbt3_s001`.`partsupp`.`ps_suppkey`,`dbt3_s001`.`partsupp`.`ps_suppkey` in ( <materialize> (select `dbt3_s001`.`supplier`.`s_suppkey` from `dbt3_s001`.`supplier` where (`dbt3_s001`.`supplier`.`s_comment` like '%Customer%Complaints%') ), <primary_index_lookup>(`dbt3_s001`.`partsupp`.`ps_suppkey` in <temporary table> on distinct_key where ((`dbt3_s001`.`partsupp`.`ps_suppkey` = `<subquery2>`.`s_suppkey`))))))))) group by `dbt3_s001`.`part`.`p_brand`,`dbt3_s001`.`part`.`p_type`,`dbt3_s001`.`part`.`p_size` order by count(distinct `dbt3_s001`.`partsupp`.`ps_suppkey`) desc,`dbt3_s001`.`part`.`p_brand`,`dbt3_s001`.`part`.`p_type`,`dbt3_s001`.`part`.`p_size` +select p_brand, p_type, p_size, count(distinct ps_suppkey) as supplier_cnt +from partsupp, part +where p_partkey = ps_partkey +and p_brand <> 'Brand#11' + and p_type not like 'SMALL POLISHED%' + and p_size in (49, 37, 27, 5, 40, 6, 22, 8) +and ps_suppkey not in (select s_suppkey from supplier +where s_comment like '%Customer%Complaints%') +group by p_brand, p_type, p_size +order by supplier_cnt desc, p_brand, p_type, p_size; +p_brand p_type p_size supplier_cnt +Brand#21 MEDIUM ANODIZED TIN 8 4 +Brand#22 PROMO PLATED TIN 5 4 +Brand#24 MEDIUM BURNISHED NICKEL 6 4 +Brand#24 SMALL ANODIZED STEEL 40 4 +Brand#32 MEDIUM BURNISHED BRASS 49 4 +Brand#33 MEDIUM POLISHED BRASS 49 4 +Brand#41 STANDARD BRUSHED NICKEL 40 4 +Brand#44 PROMO POLISHED STEEL 5 4 +Brand#45 PROMO ANODIZED BRASS 22 4 +Brand#53 STANDARD BRUSHED STEEL 27 4 +Brand#54 MEDIUM POLISHED BRASS 22 4 +Brand#54 STANDARD ANODIZED BRASS 22 4 +Brand#13 LARGE BRUSHED STEEL 8 2 +Brand#25 ECONOMY BURNISHED COPPER 27 2 +Brand#44 STANDARD PLATED TIN 37 1 +Brand#51 ECONOMY POLISHED STEEL 49 1 +set optimizer_use_condition_selectivity=3; +EXPLAIN EXTENDED select p_brand, p_type, p_size, count(distinct ps_suppkey) as supplier_cnt +from partsupp, part +where p_partkey = ps_partkey +and p_brand <> 'Brand#11' + and p_type not like 'SMALL POLISHED%' + and p_size in (49, 37, 27, 5, 40, 6, 22, 8) +and ps_suppkey not in (select s_suppkey from supplier +where s_comment like '%Customer%Complaints%') +group by p_brand, p_type, p_size +order by supplier_cnt desc, p_brand, p_type, p_size; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 16.67 Using where; Using temporary; Using filesort +1 PRIMARY partsupp ref PRIMARY,i_ps_partkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 Using where; Using index +2 MATERIALIZED supplier ALL PRIMARY NULL NULL NULL 10 100.00 Using where +Warnings: +Note 1003 select `dbt3_s001`.`part`.`p_brand` AS `p_brand`,`dbt3_s001`.`part`.`p_type` AS `p_type`,`dbt3_s001`.`part`.`p_size` AS `p_size`,count(distinct `dbt3_s001`.`partsupp`.`ps_suppkey`) AS `supplier_cnt` from `dbt3_s001`.`partsupp` join `dbt3_s001`.`part` where ((`dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey`) and (`dbt3_s001`.`part`.`p_brand` <> 'Brand#11') and (not((`dbt3_s001`.`part`.`p_type` like 'SMALL POLISHED%'))) and (`dbt3_s001`.`part`.`p_size` in (49,37,27,5,40,6,22,8)) and (not(<expr_cache><`dbt3_s001`.`partsupp`.`ps_suppkey`>(<in_optimizer>(`dbt3_s001`.`partsupp`.`ps_suppkey`,`dbt3_s001`.`partsupp`.`ps_suppkey` in ( <materialize> (select `dbt3_s001`.`supplier`.`s_suppkey` from `dbt3_s001`.`supplier` where (`dbt3_s001`.`supplier`.`s_comment` like '%Customer%Complaints%') ), <primary_index_lookup>(`dbt3_s001`.`partsupp`.`ps_suppkey` in <temporary table> on distinct_key where ((`dbt3_s001`.`partsupp`.`ps_suppkey` = `<subquery2>`.`s_suppkey`))))))))) group by `dbt3_s001`.`part`.`p_brand`,`dbt3_s001`.`part`.`p_type`,`dbt3_s001`.`part`.`p_size` order by count(distinct `dbt3_s001`.`partsupp`.`ps_suppkey`) desc,`dbt3_s001`.`part`.`p_brand`,`dbt3_s001`.`part`.`p_type`,`dbt3_s001`.`part`.`p_size` +select p_brand, p_type, p_size, count(distinct ps_suppkey) as supplier_cnt +from partsupp, part +where p_partkey = ps_partkey +and p_brand <> 'Brand#11' + and p_type not like 'SMALL POLISHED%' + and p_size in (49, 37, 27, 5, 40, 6, 22, 8) +and ps_suppkey not in (select s_suppkey from supplier +where s_comment like '%Customer%Complaints%') +group by p_brand, p_type, p_size +order by supplier_cnt desc, p_brand, p_type, p_size; +p_brand p_type p_size supplier_cnt +Brand#21 MEDIUM ANODIZED TIN 8 4 +Brand#22 PROMO PLATED TIN 5 4 +Brand#24 MEDIUM BURNISHED NICKEL 6 4 +Brand#24 SMALL ANODIZED STEEL 40 4 +Brand#32 MEDIUM BURNISHED BRASS 49 4 +Brand#33 MEDIUM POLISHED BRASS 49 4 +Brand#41 STANDARD BRUSHED NICKEL 40 4 +Brand#44 PROMO POLISHED STEEL 5 4 +Brand#45 PROMO ANODIZED BRASS 22 4 +Brand#53 STANDARD BRUSHED STEEL 27 4 +Brand#54 MEDIUM POLISHED BRASS 22 4 +Brand#54 STANDARD ANODIZED BRASS 22 4 +Brand#13 LARGE BRUSHED STEEL 8 2 +Brand#25 ECONOMY BURNISHED COPPER 27 2 +Brand#44 STANDARD PLATED TIN 37 1 +Brand#51 ECONOMY POLISHED STEEL 49 1 +set optimizer_use_condition_selectivity=4; +EXPLAIN EXTENDED select p_brand, p_type, p_size, count(distinct ps_suppkey) as supplier_cnt +from partsupp, part +where p_partkey = ps_partkey +and p_brand <> 'Brand#11' + and p_type not like 'SMALL POLISHED%' + and p_size in (49, 37, 27, 5, 40, 6, 22, 8) +and ps_suppkey not in (select s_suppkey from supplier +where s_comment like '%Customer%Complaints%') +group by p_brand, p_type, p_size +order by supplier_cnt desc, p_brand, p_type, p_size; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 16.67 Using where; Using temporary; Using filesort +1 PRIMARY partsupp ref PRIMARY,i_ps_partkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 Using where; Using index +2 MATERIALIZED supplier ALL PRIMARY NULL NULL NULL 10 100.00 Using where +Warnings: +Note 1003 select `dbt3_s001`.`part`.`p_brand` AS `p_brand`,`dbt3_s001`.`part`.`p_type` AS `p_type`,`dbt3_s001`.`part`.`p_size` AS `p_size`,count(distinct `dbt3_s001`.`partsupp`.`ps_suppkey`) AS `supplier_cnt` from `dbt3_s001`.`partsupp` join `dbt3_s001`.`part` where ((`dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey`) and (`dbt3_s001`.`part`.`p_brand` <> 'Brand#11') and (not((`dbt3_s001`.`part`.`p_type` like 'SMALL POLISHED%'))) and (`dbt3_s001`.`part`.`p_size` in (49,37,27,5,40,6,22,8)) and (not(<expr_cache><`dbt3_s001`.`partsupp`.`ps_suppkey`>(<in_optimizer>(`dbt3_s001`.`partsupp`.`ps_suppkey`,`dbt3_s001`.`partsupp`.`ps_suppkey` in ( <materialize> (select `dbt3_s001`.`supplier`.`s_suppkey` from `dbt3_s001`.`supplier` where (`dbt3_s001`.`supplier`.`s_comment` like '%Customer%Complaints%') ), <primary_index_lookup>(`dbt3_s001`.`partsupp`.`ps_suppkey` in <temporary table> on distinct_key where ((`dbt3_s001`.`partsupp`.`ps_suppkey` = `<subquery2>`.`s_suppkey`))))))))) group by `dbt3_s001`.`part`.`p_brand`,`dbt3_s001`.`part`.`p_type`,`dbt3_s001`.`part`.`p_size` order by count(distinct `dbt3_s001`.`partsupp`.`ps_suppkey`) desc,`dbt3_s001`.`part`.`p_brand`,`dbt3_s001`.`part`.`p_type`,`dbt3_s001`.`part`.`p_size` +select p_brand, p_type, p_size, count(distinct ps_suppkey) as supplier_cnt +from partsupp, part +where p_partkey = ps_partkey +and p_brand <> 'Brand#11' + and p_type not like 'SMALL POLISHED%' + and p_size in (49, 37, 27, 5, 40, 6, 22, 8) +and ps_suppkey not in (select s_suppkey from supplier +where s_comment like '%Customer%Complaints%') +group by p_brand, p_type, p_size +order by supplier_cnt desc, p_brand, p_type, p_size; +p_brand p_type p_size supplier_cnt +Brand#21 MEDIUM ANODIZED TIN 8 4 +Brand#22 PROMO PLATED TIN 5 4 +Brand#24 MEDIUM BURNISHED NICKEL 6 4 +Brand#24 SMALL ANODIZED STEEL 40 4 +Brand#32 MEDIUM BURNISHED BRASS 49 4 +Brand#33 MEDIUM POLISHED BRASS 49 4 +Brand#41 STANDARD BRUSHED NICKEL 40 4 +Brand#44 PROMO POLISHED STEEL 5 4 +Brand#45 PROMO ANODIZED BRASS 22 4 +Brand#53 STANDARD BRUSHED STEEL 27 4 +Brand#54 MEDIUM POLISHED BRASS 22 4 +Brand#54 STANDARD ANODIZED BRASS 22 4 +Brand#13 LARGE BRUSHED STEEL 8 2 +Brand#25 ECONOMY BURNISHED COPPER 27 2 +Brand#44 STANDARD PLATED TIN 37 1 +Brand#51 ECONOMY POLISHED STEEL 49 1 +=== Q18 === +set optimizer_use_condition_selectivity=1; +EXPLAIN EXTENDED select +c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice, sum(l_quantity) +from customer, orders, lineitem +where +o_orderkey in (select l_orderkey from lineitem +group by l_orderkey having sum(l_quantity) > 250) +and c_custkey = o_custkey +and o_orderkey = l_orderkey +group by c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice +order by o_totalprice desc, o_orderdate; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY orders ALL PRIMARY,i_o_custkey NULL NULL NULL 1500 100.00 Using where; Using temporary; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 dbt3_s001.orders.o_orderkey 1 100.00 +1 PRIMARY customer eq_ref PRIMARY PRIMARY 4 dbt3_s001.orders.o_custkey 1 100.00 +1 PRIMARY lineitem ref PRIMARY,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey_quantity 4 dbt3_s001.orders.o_orderkey 4 100.00 Using index +2 MATERIALIZED lineitem index NULL i_l_orderkey_quantity 13 NULL 6005 100.00 Using index +Warnings: +Note 1003 select `dbt3_s001`.`customer`.`c_name` AS `c_name`,`dbt3_s001`.`customer`.`c_custkey` AS `c_custkey`,`dbt3_s001`.`orders`.`o_orderkey` AS `o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE` AS `o_orderdate`,`dbt3_s001`.`orders`.`o_totalprice` AS `o_totalprice`,sum(`dbt3_s001`.`lineitem`.`l_quantity`) AS `sum(l_quantity)` from <materialize> (select `dbt3_s001`.`lineitem`.`l_orderkey` from `dbt3_s001`.`lineitem` group by `dbt3_s001`.`lineitem`.`l_orderkey` having (sum(`dbt3_s001`.`lineitem`.`l_quantity`) > 250)) join `dbt3_s001`.`customer` join `dbt3_s001`.`orders` join `dbt3_s001`.`lineitem` where ((`<subquery2>`.`l_orderkey` = `dbt3_s001`.`orders`.`o_orderkey`) and (`dbt3_s001`.`lineitem`.`l_orderkey` = `dbt3_s001`.`orders`.`o_orderkey`) and (`dbt3_s001`.`customer`.`c_custkey` = `dbt3_s001`.`orders`.`o_custkey`)) group by `dbt3_s001`.`customer`.`c_name`,`dbt3_s001`.`customer`.`c_custkey`,`dbt3_s001`.`orders`.`o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE`,`dbt3_s001`.`orders`.`o_totalprice` order by `dbt3_s001`.`orders`.`o_totalprice` desc,`dbt3_s001`.`orders`.`o_orderDATE` +select +c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice, sum(l_quantity) +from customer, orders, lineitem +where +o_orderkey in (select l_orderkey from lineitem +group by l_orderkey having sum(l_quantity) > 250) +and c_custkey = o_custkey +and o_orderkey = l_orderkey +group by c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice +order by o_totalprice desc, o_orderdate; +c_name c_custkey o_orderkey o_orderdate o_totalprice sum(l_quantity) +Customer#000000070 70 2567 1998-02-27 263411.29 266 +Customer#000000010 10 4421 1997-04-04 258779.02 255 +Customer#000000082 82 3460 1995-10-03 245976.74 254 +Customer#000000068 68 2208 1995-05-01 245388.06 256 +set optimizer_use_condition_selectivity=3; +EXPLAIN EXTENDED select +c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice, sum(l_quantity) +from customer, orders, lineitem +where +o_orderkey in (select l_orderkey from lineitem +group by l_orderkey having sum(l_quantity) > 250) +and c_custkey = o_custkey +and o_orderkey = l_orderkey +group by c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice +order by o_totalprice desc, o_orderdate; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY orders ALL PRIMARY,i_o_custkey NULL NULL NULL 1500 100.00 Using where; Using temporary; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 dbt3_s001.orders.o_orderkey 1 100.00 +1 PRIMARY customer eq_ref PRIMARY PRIMARY 4 dbt3_s001.orders.o_custkey 1 100.00 +1 PRIMARY lineitem ref PRIMARY,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey_quantity 4 dbt3_s001.orders.o_orderkey 4 100.00 Using index +2 MATERIALIZED lineitem index NULL i_l_orderkey_quantity 13 NULL 6005 100.00 Using index +Warnings: +Note 1003 select `dbt3_s001`.`customer`.`c_name` AS `c_name`,`dbt3_s001`.`customer`.`c_custkey` AS `c_custkey`,`dbt3_s001`.`orders`.`o_orderkey` AS `o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE` AS `o_orderdate`,`dbt3_s001`.`orders`.`o_totalprice` AS `o_totalprice`,sum(`dbt3_s001`.`lineitem`.`l_quantity`) AS `sum(l_quantity)` from <materialize> (select `dbt3_s001`.`lineitem`.`l_orderkey` from `dbt3_s001`.`lineitem` group by `dbt3_s001`.`lineitem`.`l_orderkey` having (sum(`dbt3_s001`.`lineitem`.`l_quantity`) > 250)) join `dbt3_s001`.`customer` join `dbt3_s001`.`orders` join `dbt3_s001`.`lineitem` where ((`<subquery2>`.`l_orderkey` = `dbt3_s001`.`orders`.`o_orderkey`) and (`dbt3_s001`.`lineitem`.`l_orderkey` = `dbt3_s001`.`orders`.`o_orderkey`) and (`dbt3_s001`.`customer`.`c_custkey` = `dbt3_s001`.`orders`.`o_custkey`)) group by `dbt3_s001`.`customer`.`c_name`,`dbt3_s001`.`customer`.`c_custkey`,`dbt3_s001`.`orders`.`o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE`,`dbt3_s001`.`orders`.`o_totalprice` order by `dbt3_s001`.`orders`.`o_totalprice` desc,`dbt3_s001`.`orders`.`o_orderDATE` +select +c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice, sum(l_quantity) +from customer, orders, lineitem +where +o_orderkey in (select l_orderkey from lineitem +group by l_orderkey having sum(l_quantity) > 250) +and c_custkey = o_custkey +and o_orderkey = l_orderkey +group by c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice +order by o_totalprice desc, o_orderdate; +c_name c_custkey o_orderkey o_orderdate o_totalprice sum(l_quantity) +Customer#000000070 70 2567 1998-02-27 263411.29 266 +Customer#000000010 10 4421 1997-04-04 258779.02 255 +Customer#000000082 82 3460 1995-10-03 245976.74 254 +Customer#000000068 68 2208 1995-05-01 245388.06 256 +=== Q22 === +set optimizer_use_condition_selectivity=1; +EXPLAIN EXTENDED select cntrycode, count(*) as numcust, sum(c_acctbal) as totacctbal +from ( +select substr(c_phone, 1, 2) as cntrycode, c_acctbal +from customer +where +substr(c_phone, 1, 2) in ('10', '20', '14', '19', '11', '28', '25') +and c_acctbal > (select avg(c_acctbal) from customer +where c_acctbal > 0.00 +and substr(c_phone, 1, 2) in +('10', '20', '14', '19', '11', '28', '25')) +and not exists (select * from orders where o_custkey = c_custkey) +) as vip +group by cntrycode +order by cntrycode; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE customer ALL NULL NULL NULL NULL 150 100.00 Using where; Using temporary; Using filesort +4 DEPENDENT SUBQUERY orders ref i_o_custkey i_o_custkey 5 dbt3_s001.customer.c_custkey 15 100.00 Using index +3 SUBQUERY customer ALL NULL NULL NULL NULL 150 100.00 Using where +Warnings: +Note 1276 Field or reference 'dbt3_s001.customer.c_custkey' of SELECT #4 was resolved in SELECT #2 +Note 1003 select substr(`dbt3_s001`.`customer`.`c_phone`,1,2) AS `cntrycode`,count(0) AS `numcust`,sum(`dbt3_s001`.`customer`.`c_acctbal`) AS `totacctbal` from `dbt3_s001`.`customer` where ((substr(`dbt3_s001`.`customer`.`c_phone`,1,2) in ('10','20','14','19','11','28','25')) and (`dbt3_s001`.`customer`.`c_acctbal` > (select avg(`dbt3_s001`.`customer`.`c_acctbal`) from `dbt3_s001`.`customer` where ((`dbt3_s001`.`customer`.`c_acctbal` > 0.00) and (substr(`dbt3_s001`.`customer`.`c_phone`,1,2) in ('10','20','14','19','11','28','25'))))) and (not(exists(select 1 from `dbt3_s001`.`orders` where (`dbt3_s001`.`orders`.`o_custkey` = `dbt3_s001`.`customer`.`c_custkey`))))) group by substr(`dbt3_s001`.`customer`.`c_phone`,1,2) order by substr(`dbt3_s001`.`customer`.`c_phone`,1,2) +select cntrycode, count(*) as numcust, sum(c_acctbal) as totacctbal +from ( +select substr(c_phone, 1, 2) as cntrycode, c_acctbal +from customer +where +substr(c_phone, 1, 2) in ('10', '20', '14', '19', '11', '28', '25') +and c_acctbal > (select avg(c_acctbal) from customer +where c_acctbal > 0.00 +and substr(c_phone, 1, 2) in +('10', '20', '14', '19', '11', '28', '25')) +and not exists (select * from orders where o_custkey = c_custkey) +) as vip +group by cntrycode +order by cntrycode; +cntrycode numcust totacctbal +11 4 29942.58 +19 2 17120.35 +20 1 9091.82 +28 2 14755.5 +set optimizer_use_condition_selectivity=3; +EXPLAIN EXTENDED select cntrycode, count(*) as numcust, sum(c_acctbal) as totacctbal +from ( +select substr(c_phone, 1, 2) as cntrycode, c_acctbal +from customer +where +substr(c_phone, 1, 2) in ('10', '20', '14', '19', '11', '28', '25') +and c_acctbal > (select avg(c_acctbal) from customer +where c_acctbal > 0.00 +and substr(c_phone, 1, 2) in +('10', '20', '14', '19', '11', '28', '25')) +and not exists (select * from orders where o_custkey = c_custkey) +) as vip +group by cntrycode +order by cntrycode; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE customer ALL NULL NULL NULL NULL 150 100.00 Using where; Using temporary; Using filesort +4 DEPENDENT SUBQUERY orders ref i_o_custkey i_o_custkey 5 dbt3_s001.customer.c_custkey 15 100.00 Using index +3 SUBQUERY customer ALL NULL NULL NULL NULL 150 91.00 Using where +Warnings: +Note 1276 Field or reference 'dbt3_s001.customer.c_custkey' of SELECT #4 was resolved in SELECT #2 +Note 1003 select substr(`dbt3_s001`.`customer`.`c_phone`,1,2) AS `cntrycode`,count(0) AS `numcust`,sum(`dbt3_s001`.`customer`.`c_acctbal`) AS `totacctbal` from `dbt3_s001`.`customer` where ((substr(`dbt3_s001`.`customer`.`c_phone`,1,2) in ('10','20','14','19','11','28','25')) and (`dbt3_s001`.`customer`.`c_acctbal` > (select avg(`dbt3_s001`.`customer`.`c_acctbal`) from `dbt3_s001`.`customer` where ((`dbt3_s001`.`customer`.`c_acctbal` > 0.00) and (substr(`dbt3_s001`.`customer`.`c_phone`,1,2) in ('10','20','14','19','11','28','25'))))) and (not(exists(select 1 from `dbt3_s001`.`orders` where (`dbt3_s001`.`orders`.`o_custkey` = `dbt3_s001`.`customer`.`c_custkey`))))) group by substr(`dbt3_s001`.`customer`.`c_phone`,1,2) order by substr(`dbt3_s001`.`customer`.`c_phone`,1,2) +select cntrycode, count(*) as numcust, sum(c_acctbal) as totacctbal +from ( +select substr(c_phone, 1, 2) as cntrycode, c_acctbal +from customer +where +substr(c_phone, 1, 2) in ('10', '20', '14', '19', '11', '28', '25') +and c_acctbal > (select avg(c_acctbal) from customer +where c_acctbal > 0.00 +and substr(c_phone, 1, 2) in +('10', '20', '14', '19', '11', '28', '25')) +and not exists (select * from orders where o_custkey = c_custkey) +) as vip +group by cntrycode +order by cntrycode; +cntrycode numcust totacctbal +11 4 29942.58 +19 2 17120.35 +20 1 9091.82 +28 2 14755.5 +=== Q20 === +set optimizer_use_condition_selectivity=1; EXPLAIN EXTENDED select sql_calc_found_rows s_name, s_address from supplier, nation diff --git a/mysql-test/r/selectivity_innodb.result b/mysql-test/r/selectivity_innodb.result index 9ececad3492..6fbff38000d 100644 --- a/mysql-test/r/selectivity_innodb.result +++ b/mysql-test/r/selectivity_innodb.result @@ -14,6 +14,347 @@ CREATE DATABASE dbt3_s001; use dbt3_s001; set @save_optimizer_use_condition_selectivity=@@optimizer_use_condition_selectivity; set @save_histogram_size=@@histogram_size; +=== Q15 === +create view revenue0 (supplier_no, total_revenue) as +select l_suppkey, sum(l_extendedprice * (1 - l_discount)) +from lineitem +where +l_shipdate >= '1995-08-01' + and l_shipdate < date_add('1995-08-01', interval 90 day) +group by l_suppkey; +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='index_condition_pushdown=off'; +set optimizer_use_condition_selectivity=1; +EXPLAIN EXTENDED select s_suppkey, s_name, s_address, s_phone, total_revenue +from supplier, revenue0 +where s_suppkey = supplier_no +and total_revenue = (select max(total_revenue) from revenue0) +order by s_suppkey; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY supplier index PRIMARY PRIMARY 4 NULL 10 100.00 +1 PRIMARY <derived3> ref key0 key0 5 dbt3_s001.supplier.s_suppkey 10 100.00 Using where +3 DERIVED lineitem range i_l_shipdate i_l_shipdate 4 NULL 228 100.00 Using where; Using temporary; Using filesort +2 SUBQUERY <derived4> ALL NULL NULL NULL NULL 228 100.00 +4 DERIVED lineitem range i_l_shipdate i_l_shipdate 4 NULL 228 100.00 Using where; Using temporary; Using filesort +Warnings: +Note 1003 select `dbt3_s001`.`supplier`.`s_suppkey` AS `s_suppkey`,`dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`supplier`.`s_address` AS `s_address`,`dbt3_s001`.`supplier`.`s_phone` AS `s_phone`,`revenue0`.`total_revenue` AS `total_revenue` from `dbt3_s001`.`supplier` join `dbt3_s001`.`revenue0` where ((`revenue0`.`supplier_no` = `dbt3_s001`.`supplier`.`s_suppkey`) and (`revenue0`.`total_revenue` = (select max(`revenue0`.`total_revenue`) from `dbt3_s001`.`revenue0`))) order by `dbt3_s001`.`supplier`.`s_suppkey` +select s_suppkey, s_name, s_address, s_phone, total_revenue +from supplier, revenue0 +where s_suppkey = supplier_no +and total_revenue = (select max(total_revenue) from revenue0) +order by s_suppkey; +s_suppkey s_name s_address s_phone total_revenue +1 Supplier#000000001 N kD4on9OM Ipw3,gf0JBoQDd7tgrzrddZ 27-918-335-1736 729084.7773 +set optimizer_use_condition_selectivity=3; +EXPLAIN EXTENDED select s_suppkey, s_name, s_address, s_phone, total_revenue +from supplier, revenue0 +where s_suppkey = supplier_no +and total_revenue = (select max(total_revenue) from revenue0) +order by s_suppkey; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY supplier index PRIMARY PRIMARY 4 NULL 10 100.00 +1 PRIMARY <derived3> ref key0 key0 5 dbt3_s001.supplier.s_suppkey 10 100.00 Using where +3 DERIVED lineitem range i_l_shipdate i_l_shipdate 4 NULL 228 0.14 Using where; Using temporary; Using filesort +2 SUBQUERY <derived4> ALL NULL NULL NULL NULL 228 100.00 +4 DERIVED lineitem range i_l_shipdate i_l_shipdate 4 NULL 228 0.14 Using where; Using temporary; Using filesort +Warnings: +Note 1003 select `dbt3_s001`.`supplier`.`s_suppkey` AS `s_suppkey`,`dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`supplier`.`s_address` AS `s_address`,`dbt3_s001`.`supplier`.`s_phone` AS `s_phone`,`revenue0`.`total_revenue` AS `total_revenue` from `dbt3_s001`.`supplier` join `dbt3_s001`.`revenue0` where ((`revenue0`.`supplier_no` = `dbt3_s001`.`supplier`.`s_suppkey`) and (`revenue0`.`total_revenue` = (select max(`revenue0`.`total_revenue`) from `dbt3_s001`.`revenue0`))) order by `dbt3_s001`.`supplier`.`s_suppkey` +select s_suppkey, s_name, s_address, s_phone, total_revenue +from supplier, revenue0 +where s_suppkey = supplier_no +and total_revenue = (select max(total_revenue) from revenue0) +order by s_suppkey; +s_suppkey s_name s_address s_phone total_revenue +1 Supplier#000000001 N kD4on9OM Ipw3,gf0JBoQDd7tgrzrddZ 27-918-335-1736 729084.7773 +set optimizer_switch=@save_optimizer_switch; +drop view revenue0; +=== Q16 === +set optimizer_use_condition_selectivity=1; +EXPLAIN EXTENDED select p_brand, p_type, p_size, count(distinct ps_suppkey) as supplier_cnt +from partsupp, part +where p_partkey = ps_partkey +and p_brand <> 'Brand#11' + and p_type not like 'SMALL POLISHED%' + and p_size in (49, 37, 27, 5, 40, 6, 22, 8) +and ps_suppkey not in (select s_suppkey from supplier +where s_comment like '%Customer%Complaints%') +group by p_brand, p_type, p_size +order by supplier_cnt desc, p_brand, p_type, p_size; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 100.00 Using where; Using temporary; Using filesort +1 PRIMARY partsupp ref PRIMARY,i_ps_partkey i_ps_partkey 4 dbt3_s001.part.p_partkey 3 100.00 Using where; Using index +2 MATERIALIZED supplier ALL PRIMARY NULL NULL NULL 10 100.00 Using where +Warnings: +Note 1003 select `dbt3_s001`.`part`.`p_brand` AS `p_brand`,`dbt3_s001`.`part`.`p_type` AS `p_type`,`dbt3_s001`.`part`.`p_size` AS `p_size`,count(distinct `dbt3_s001`.`partsupp`.`ps_suppkey`) AS `supplier_cnt` from `dbt3_s001`.`partsupp` join `dbt3_s001`.`part` where ((`dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey`) and (`dbt3_s001`.`part`.`p_brand` <> 'Brand#11') and (not((`dbt3_s001`.`part`.`p_type` like 'SMALL POLISHED%'))) and (`dbt3_s001`.`part`.`p_size` in (49,37,27,5,40,6,22,8)) and (not(<expr_cache><`dbt3_s001`.`partsupp`.`ps_suppkey`>(<in_optimizer>(`dbt3_s001`.`partsupp`.`ps_suppkey`,`dbt3_s001`.`partsupp`.`ps_suppkey` in ( <materialize> (select `dbt3_s001`.`supplier`.`s_suppkey` from `dbt3_s001`.`supplier` where (`dbt3_s001`.`supplier`.`s_comment` like '%Customer%Complaints%') ), <primary_index_lookup>(`dbt3_s001`.`partsupp`.`ps_suppkey` in <temporary table> on distinct_key where ((`dbt3_s001`.`partsupp`.`ps_suppkey` = `<subquery2>`.`s_suppkey`))))))))) group by `dbt3_s001`.`part`.`p_brand`,`dbt3_s001`.`part`.`p_type`,`dbt3_s001`.`part`.`p_size` order by count(distinct `dbt3_s001`.`partsupp`.`ps_suppkey`) desc,`dbt3_s001`.`part`.`p_brand`,`dbt3_s001`.`part`.`p_type`,`dbt3_s001`.`part`.`p_size` +select p_brand, p_type, p_size, count(distinct ps_suppkey) as supplier_cnt +from partsupp, part +where p_partkey = ps_partkey +and p_brand <> 'Brand#11' + and p_type not like 'SMALL POLISHED%' + and p_size in (49, 37, 27, 5, 40, 6, 22, 8) +and ps_suppkey not in (select s_suppkey from supplier +where s_comment like '%Customer%Complaints%') +group by p_brand, p_type, p_size +order by supplier_cnt desc, p_brand, p_type, p_size; +p_brand p_type p_size supplier_cnt +Brand#21 MEDIUM ANODIZED TIN 8 4 +Brand#22 PROMO PLATED TIN 5 4 +Brand#24 MEDIUM BURNISHED NICKEL 6 4 +Brand#24 SMALL ANODIZED STEEL 40 4 +Brand#32 MEDIUM BURNISHED BRASS 49 4 +Brand#33 MEDIUM POLISHED BRASS 49 4 +Brand#41 STANDARD BRUSHED NICKEL 40 4 +Brand#44 PROMO POLISHED STEEL 5 4 +Brand#45 PROMO ANODIZED BRASS 22 4 +Brand#53 STANDARD BRUSHED STEEL 27 4 +Brand#54 MEDIUM POLISHED BRASS 22 4 +Brand#54 STANDARD ANODIZED BRASS 22 4 +Brand#13 LARGE BRUSHED STEEL 8 2 +Brand#25 ECONOMY BURNISHED COPPER 27 2 +Brand#44 STANDARD PLATED TIN 37 1 +Brand#51 ECONOMY POLISHED STEEL 49 1 +set optimizer_use_condition_selectivity=3; +EXPLAIN EXTENDED select p_brand, p_type, p_size, count(distinct ps_suppkey) as supplier_cnt +from partsupp, part +where p_partkey = ps_partkey +and p_brand <> 'Brand#11' + and p_type not like 'SMALL POLISHED%' + and p_size in (49, 37, 27, 5, 40, 6, 22, 8) +and ps_suppkey not in (select s_suppkey from supplier +where s_comment like '%Customer%Complaints%') +group by p_brand, p_type, p_size +order by supplier_cnt desc, p_brand, p_type, p_size; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 16.67 Using where; Using temporary; Using filesort +1 PRIMARY partsupp ref PRIMARY,i_ps_partkey i_ps_partkey 4 dbt3_s001.part.p_partkey 3 100.00 Using where; Using index +2 MATERIALIZED supplier ALL PRIMARY NULL NULL NULL 10 100.00 Using where +Warnings: +Note 1003 select `dbt3_s001`.`part`.`p_brand` AS `p_brand`,`dbt3_s001`.`part`.`p_type` AS `p_type`,`dbt3_s001`.`part`.`p_size` AS `p_size`,count(distinct `dbt3_s001`.`partsupp`.`ps_suppkey`) AS `supplier_cnt` from `dbt3_s001`.`partsupp` join `dbt3_s001`.`part` where ((`dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey`) and (`dbt3_s001`.`part`.`p_brand` <> 'Brand#11') and (not((`dbt3_s001`.`part`.`p_type` like 'SMALL POLISHED%'))) and (`dbt3_s001`.`part`.`p_size` in (49,37,27,5,40,6,22,8)) and (not(<expr_cache><`dbt3_s001`.`partsupp`.`ps_suppkey`>(<in_optimizer>(`dbt3_s001`.`partsupp`.`ps_suppkey`,`dbt3_s001`.`partsupp`.`ps_suppkey` in ( <materialize> (select `dbt3_s001`.`supplier`.`s_suppkey` from `dbt3_s001`.`supplier` where (`dbt3_s001`.`supplier`.`s_comment` like '%Customer%Complaints%') ), <primary_index_lookup>(`dbt3_s001`.`partsupp`.`ps_suppkey` in <temporary table> on distinct_key where ((`dbt3_s001`.`partsupp`.`ps_suppkey` = `<subquery2>`.`s_suppkey`))))))))) group by `dbt3_s001`.`part`.`p_brand`,`dbt3_s001`.`part`.`p_type`,`dbt3_s001`.`part`.`p_size` order by count(distinct `dbt3_s001`.`partsupp`.`ps_suppkey`) desc,`dbt3_s001`.`part`.`p_brand`,`dbt3_s001`.`part`.`p_type`,`dbt3_s001`.`part`.`p_size` +select p_brand, p_type, p_size, count(distinct ps_suppkey) as supplier_cnt +from partsupp, part +where p_partkey = ps_partkey +and p_brand <> 'Brand#11' + and p_type not like 'SMALL POLISHED%' + and p_size in (49, 37, 27, 5, 40, 6, 22, 8) +and ps_suppkey not in (select s_suppkey from supplier +where s_comment like '%Customer%Complaints%') +group by p_brand, p_type, p_size +order by supplier_cnt desc, p_brand, p_type, p_size; +p_brand p_type p_size supplier_cnt +Brand#21 MEDIUM ANODIZED TIN 8 4 +Brand#22 PROMO PLATED TIN 5 4 +Brand#24 MEDIUM BURNISHED NICKEL 6 4 +Brand#24 SMALL ANODIZED STEEL 40 4 +Brand#32 MEDIUM BURNISHED BRASS 49 4 +Brand#33 MEDIUM POLISHED BRASS 49 4 +Brand#41 STANDARD BRUSHED NICKEL 40 4 +Brand#44 PROMO POLISHED STEEL 5 4 +Brand#45 PROMO ANODIZED BRASS 22 4 +Brand#53 STANDARD BRUSHED STEEL 27 4 +Brand#54 MEDIUM POLISHED BRASS 22 4 +Brand#54 STANDARD ANODIZED BRASS 22 4 +Brand#13 LARGE BRUSHED STEEL 8 2 +Brand#25 ECONOMY BURNISHED COPPER 27 2 +Brand#44 STANDARD PLATED TIN 37 1 +Brand#51 ECONOMY POLISHED STEEL 49 1 +set optimizer_use_condition_selectivity=4; +EXPLAIN EXTENDED select p_brand, p_type, p_size, count(distinct ps_suppkey) as supplier_cnt +from partsupp, part +where p_partkey = ps_partkey +and p_brand <> 'Brand#11' + and p_type not like 'SMALL POLISHED%' + and p_size in (49, 37, 27, 5, 40, 6, 22, 8) +and ps_suppkey not in (select s_suppkey from supplier +where s_comment like '%Customer%Complaints%') +group by p_brand, p_type, p_size +order by supplier_cnt desc, p_brand, p_type, p_size; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 16.67 Using where; Using temporary; Using filesort +1 PRIMARY partsupp ref PRIMARY,i_ps_partkey i_ps_partkey 4 dbt3_s001.part.p_partkey 3 100.00 Using where; Using index +2 MATERIALIZED supplier ALL PRIMARY NULL NULL NULL 10 100.00 Using where +Warnings: +Note 1003 select `dbt3_s001`.`part`.`p_brand` AS `p_brand`,`dbt3_s001`.`part`.`p_type` AS `p_type`,`dbt3_s001`.`part`.`p_size` AS `p_size`,count(distinct `dbt3_s001`.`partsupp`.`ps_suppkey`) AS `supplier_cnt` from `dbt3_s001`.`partsupp` join `dbt3_s001`.`part` where ((`dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey`) and (`dbt3_s001`.`part`.`p_brand` <> 'Brand#11') and (not((`dbt3_s001`.`part`.`p_type` like 'SMALL POLISHED%'))) and (`dbt3_s001`.`part`.`p_size` in (49,37,27,5,40,6,22,8)) and (not(<expr_cache><`dbt3_s001`.`partsupp`.`ps_suppkey`>(<in_optimizer>(`dbt3_s001`.`partsupp`.`ps_suppkey`,`dbt3_s001`.`partsupp`.`ps_suppkey` in ( <materialize> (select `dbt3_s001`.`supplier`.`s_suppkey` from `dbt3_s001`.`supplier` where (`dbt3_s001`.`supplier`.`s_comment` like '%Customer%Complaints%') ), <primary_index_lookup>(`dbt3_s001`.`partsupp`.`ps_suppkey` in <temporary table> on distinct_key where ((`dbt3_s001`.`partsupp`.`ps_suppkey` = `<subquery2>`.`s_suppkey`))))))))) group by `dbt3_s001`.`part`.`p_brand`,`dbt3_s001`.`part`.`p_type`,`dbt3_s001`.`part`.`p_size` order by count(distinct `dbt3_s001`.`partsupp`.`ps_suppkey`) desc,`dbt3_s001`.`part`.`p_brand`,`dbt3_s001`.`part`.`p_type`,`dbt3_s001`.`part`.`p_size` +select p_brand, p_type, p_size, count(distinct ps_suppkey) as supplier_cnt +from partsupp, part +where p_partkey = ps_partkey +and p_brand <> 'Brand#11' + and p_type not like 'SMALL POLISHED%' + and p_size in (49, 37, 27, 5, 40, 6, 22, 8) +and ps_suppkey not in (select s_suppkey from supplier +where s_comment like '%Customer%Complaints%') +group by p_brand, p_type, p_size +order by supplier_cnt desc, p_brand, p_type, p_size; +p_brand p_type p_size supplier_cnt +Brand#21 MEDIUM ANODIZED TIN 8 4 +Brand#22 PROMO PLATED TIN 5 4 +Brand#24 MEDIUM BURNISHED NICKEL 6 4 +Brand#24 SMALL ANODIZED STEEL 40 4 +Brand#32 MEDIUM BURNISHED BRASS 49 4 +Brand#33 MEDIUM POLISHED BRASS 49 4 +Brand#41 STANDARD BRUSHED NICKEL 40 4 +Brand#44 PROMO POLISHED STEEL 5 4 +Brand#45 PROMO ANODIZED BRASS 22 4 +Brand#53 STANDARD BRUSHED STEEL 27 4 +Brand#54 MEDIUM POLISHED BRASS 22 4 +Brand#54 STANDARD ANODIZED BRASS 22 4 +Brand#13 LARGE BRUSHED STEEL 8 2 +Brand#25 ECONOMY BURNISHED COPPER 27 2 +Brand#44 STANDARD PLATED TIN 37 1 +Brand#51 ECONOMY POLISHED STEEL 49 1 +=== Q18 === +set optimizer_use_condition_selectivity=1; +EXPLAIN EXTENDED select +c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice, sum(l_quantity) +from customer, orders, lineitem +where +o_orderkey in (select l_orderkey from lineitem +group by l_orderkey having sum(l_quantity) > 250) +and c_custkey = o_custkey +and o_orderkey = l_orderkey +group by c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice +order by o_totalprice desc, o_orderdate; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY orders ALL PRIMARY,i_o_custkey NULL NULL NULL 1500 100.00 Using where; Using temporary; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 dbt3_s001.orders.o_orderkey 1 100.00 +1 PRIMARY customer eq_ref PRIMARY PRIMARY 4 dbt3_s001.orders.o_custkey 1 100.00 +1 PRIMARY lineitem ref PRIMARY,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey_quantity 4 dbt3_s001.orders.o_orderkey 4 100.00 Using index +2 MATERIALIZED lineitem index NULL PRIMARY 8 NULL 6005 100.00 +Warnings: +Note 1003 select `dbt3_s001`.`customer`.`c_name` AS `c_name`,`dbt3_s001`.`customer`.`c_custkey` AS `c_custkey`,`dbt3_s001`.`orders`.`o_orderkey` AS `o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE` AS `o_orderdate`,`dbt3_s001`.`orders`.`o_totalprice` AS `o_totalprice`,sum(`dbt3_s001`.`lineitem`.`l_quantity`) AS `sum(l_quantity)` from <materialize> (select `dbt3_s001`.`lineitem`.`l_orderkey` from `dbt3_s001`.`lineitem` group by `dbt3_s001`.`lineitem`.`l_orderkey` having (sum(`dbt3_s001`.`lineitem`.`l_quantity`) > 250)) join `dbt3_s001`.`customer` join `dbt3_s001`.`orders` join `dbt3_s001`.`lineitem` where ((`<subquery2>`.`l_orderkey` = `dbt3_s001`.`orders`.`o_orderkey`) and (`dbt3_s001`.`lineitem`.`l_orderkey` = `dbt3_s001`.`orders`.`o_orderkey`) and (`dbt3_s001`.`customer`.`c_custkey` = `dbt3_s001`.`orders`.`o_custkey`)) group by `dbt3_s001`.`customer`.`c_name`,`dbt3_s001`.`customer`.`c_custkey`,`dbt3_s001`.`orders`.`o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE`,`dbt3_s001`.`orders`.`o_totalprice` order by `dbt3_s001`.`orders`.`o_totalprice` desc,`dbt3_s001`.`orders`.`o_orderDATE` +select +c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice, sum(l_quantity) +from customer, orders, lineitem +where +o_orderkey in (select l_orderkey from lineitem +group by l_orderkey having sum(l_quantity) > 250) +and c_custkey = o_custkey +and o_orderkey = l_orderkey +group by c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice +order by o_totalprice desc, o_orderdate; +c_name c_custkey o_orderkey o_orderdate o_totalprice sum(l_quantity) +Customer#000000070 70 2567 1998-02-27 263411.29 266 +Customer#000000010 10 4421 1997-04-04 258779.02 255 +Customer#000000082 82 3460 1995-10-03 245976.74 254 +Customer#000000068 68 2208 1995-05-01 245388.06 256 +set optimizer_use_condition_selectivity=3; +EXPLAIN EXTENDED select +c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice, sum(l_quantity) +from customer, orders, lineitem +where +o_orderkey in (select l_orderkey from lineitem +group by l_orderkey having sum(l_quantity) > 250) +and c_custkey = o_custkey +and o_orderkey = l_orderkey +group by c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice +order by o_totalprice desc, o_orderdate; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY orders ALL PRIMARY,i_o_custkey NULL NULL NULL 1500 100.00 Using where; Using temporary; Using filesort +1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 dbt3_s001.orders.o_orderkey 1 100.00 +1 PRIMARY customer eq_ref PRIMARY PRIMARY 4 dbt3_s001.orders.o_custkey 1 100.00 +1 PRIMARY lineitem ref PRIMARY,i_l_orderkey,i_l_orderkey_quantity i_l_orderkey_quantity 4 dbt3_s001.orders.o_orderkey 4 100.00 Using index +2 MATERIALIZED lineitem index NULL PRIMARY 8 NULL 6005 100.00 +Warnings: +Note 1003 select `dbt3_s001`.`customer`.`c_name` AS `c_name`,`dbt3_s001`.`customer`.`c_custkey` AS `c_custkey`,`dbt3_s001`.`orders`.`o_orderkey` AS `o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE` AS `o_orderdate`,`dbt3_s001`.`orders`.`o_totalprice` AS `o_totalprice`,sum(`dbt3_s001`.`lineitem`.`l_quantity`) AS `sum(l_quantity)` from <materialize> (select `dbt3_s001`.`lineitem`.`l_orderkey` from `dbt3_s001`.`lineitem` group by `dbt3_s001`.`lineitem`.`l_orderkey` having (sum(`dbt3_s001`.`lineitem`.`l_quantity`) > 250)) join `dbt3_s001`.`customer` join `dbt3_s001`.`orders` join `dbt3_s001`.`lineitem` where ((`<subquery2>`.`l_orderkey` = `dbt3_s001`.`orders`.`o_orderkey`) and (`dbt3_s001`.`lineitem`.`l_orderkey` = `dbt3_s001`.`orders`.`o_orderkey`) and (`dbt3_s001`.`customer`.`c_custkey` = `dbt3_s001`.`orders`.`o_custkey`)) group by `dbt3_s001`.`customer`.`c_name`,`dbt3_s001`.`customer`.`c_custkey`,`dbt3_s001`.`orders`.`o_orderkey`,`dbt3_s001`.`orders`.`o_orderDATE`,`dbt3_s001`.`orders`.`o_totalprice` order by `dbt3_s001`.`orders`.`o_totalprice` desc,`dbt3_s001`.`orders`.`o_orderDATE` +select +c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice, sum(l_quantity) +from customer, orders, lineitem +where +o_orderkey in (select l_orderkey from lineitem +group by l_orderkey having sum(l_quantity) > 250) +and c_custkey = o_custkey +and o_orderkey = l_orderkey +group by c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice +order by o_totalprice desc, o_orderdate; +c_name c_custkey o_orderkey o_orderdate o_totalprice sum(l_quantity) +Customer#000000070 70 2567 1998-02-27 263411.29 266 +Customer#000000010 10 4421 1997-04-04 258779.02 255 +Customer#000000082 82 3460 1995-10-03 245976.74 254 +Customer#000000068 68 2208 1995-05-01 245388.06 256 +=== Q22 === +set optimizer_use_condition_selectivity=1; +EXPLAIN EXTENDED select cntrycode, count(*) as numcust, sum(c_acctbal) as totacctbal +from ( +select substr(c_phone, 1, 2) as cntrycode, c_acctbal +from customer +where +substr(c_phone, 1, 2) in ('10', '20', '14', '19', '11', '28', '25') +and c_acctbal > (select avg(c_acctbal) from customer +where c_acctbal > 0.00 +and substr(c_phone, 1, 2) in +('10', '20', '14', '19', '11', '28', '25')) +and not exists (select * from orders where o_custkey = c_custkey) +) as vip +group by cntrycode +order by cntrycode; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE customer ALL NULL NULL NULL NULL 150 100.00 Using where; Using temporary; Using filesort +4 DEPENDENT SUBQUERY orders ref i_o_custkey i_o_custkey 5 dbt3_s001.customer.c_custkey 15 100.00 Using index +3 SUBQUERY customer ALL NULL NULL NULL NULL 150 100.00 Using where +Warnings: +Note 1276 Field or reference 'dbt3_s001.customer.c_custkey' of SELECT #4 was resolved in SELECT #2 +Note 1003 select substr(`dbt3_s001`.`customer`.`c_phone`,1,2) AS `cntrycode`,count(0) AS `numcust`,sum(`dbt3_s001`.`customer`.`c_acctbal`) AS `totacctbal` from `dbt3_s001`.`customer` where ((substr(`dbt3_s001`.`customer`.`c_phone`,1,2) in ('10','20','14','19','11','28','25')) and (`dbt3_s001`.`customer`.`c_acctbal` > (select avg(`dbt3_s001`.`customer`.`c_acctbal`) from `dbt3_s001`.`customer` where ((`dbt3_s001`.`customer`.`c_acctbal` > 0.00) and (substr(`dbt3_s001`.`customer`.`c_phone`,1,2) in ('10','20','14','19','11','28','25'))))) and (not(exists(select 1 from `dbt3_s001`.`orders` where (`dbt3_s001`.`orders`.`o_custkey` = `dbt3_s001`.`customer`.`c_custkey`))))) group by substr(`dbt3_s001`.`customer`.`c_phone`,1,2) order by substr(`dbt3_s001`.`customer`.`c_phone`,1,2) +select cntrycode, count(*) as numcust, sum(c_acctbal) as totacctbal +from ( +select substr(c_phone, 1, 2) as cntrycode, c_acctbal +from customer +where +substr(c_phone, 1, 2) in ('10', '20', '14', '19', '11', '28', '25') +and c_acctbal > (select avg(c_acctbal) from customer +where c_acctbal > 0.00 +and substr(c_phone, 1, 2) in +('10', '20', '14', '19', '11', '28', '25')) +and not exists (select * from orders where o_custkey = c_custkey) +) as vip +group by cntrycode +order by cntrycode; +cntrycode numcust totacctbal +11 4 29942.58 +19 2 17120.35 +20 1 9091.82 +28 2 14755.5 +set optimizer_use_condition_selectivity=3; +EXPLAIN EXTENDED select cntrycode, count(*) as numcust, sum(c_acctbal) as totacctbal +from ( +select substr(c_phone, 1, 2) as cntrycode, c_acctbal +from customer +where +substr(c_phone, 1, 2) in ('10', '20', '14', '19', '11', '28', '25') +and c_acctbal > (select avg(c_acctbal) from customer +where c_acctbal > 0.00 +and substr(c_phone, 1, 2) in +('10', '20', '14', '19', '11', '28', '25')) +and not exists (select * from orders where o_custkey = c_custkey) +) as vip +group by cntrycode +order by cntrycode; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE customer ALL NULL NULL NULL NULL 150 100.00 Using where; Using temporary; Using filesort +4 DEPENDENT SUBQUERY orders ref i_o_custkey i_o_custkey 5 dbt3_s001.customer.c_custkey 15 100.00 Using index +3 SUBQUERY customer ALL NULL NULL NULL NULL 150 91.00 Using where +Warnings: +Note 1276 Field or reference 'dbt3_s001.customer.c_custkey' of SELECT #4 was resolved in SELECT #2 +Note 1003 select substr(`dbt3_s001`.`customer`.`c_phone`,1,2) AS `cntrycode`,count(0) AS `numcust`,sum(`dbt3_s001`.`customer`.`c_acctbal`) AS `totacctbal` from `dbt3_s001`.`customer` where ((substr(`dbt3_s001`.`customer`.`c_phone`,1,2) in ('10','20','14','19','11','28','25')) and (`dbt3_s001`.`customer`.`c_acctbal` > (select avg(`dbt3_s001`.`customer`.`c_acctbal`) from `dbt3_s001`.`customer` where ((`dbt3_s001`.`customer`.`c_acctbal` > 0.00) and (substr(`dbt3_s001`.`customer`.`c_phone`,1,2) in ('10','20','14','19','11','28','25'))))) and (not(exists(select 1 from `dbt3_s001`.`orders` where (`dbt3_s001`.`orders`.`o_custkey` = `dbt3_s001`.`customer`.`c_custkey`))))) group by substr(`dbt3_s001`.`customer`.`c_phone`,1,2) order by substr(`dbt3_s001`.`customer`.`c_phone`,1,2) +select cntrycode, count(*) as numcust, sum(c_acctbal) as totacctbal +from ( +select substr(c_phone, 1, 2) as cntrycode, c_acctbal +from customer +where +substr(c_phone, 1, 2) in ('10', '20', '14', '19', '11', '28', '25') +and c_acctbal > (select avg(c_acctbal) from customer +where c_acctbal > 0.00 +and substr(c_phone, 1, 2) in +('10', '20', '14', '19', '11', '28', '25')) +and not exists (select * from orders where o_custkey = c_custkey) +) as vip +group by cntrycode +order by cntrycode; +cntrycode numcust totacctbal +11 4 29942.58 +19 2 17120.35 +20 1 9091.82 +28 2 14755.5 +=== Q20 === +set optimizer_use_condition_selectivity=1; EXPLAIN EXTENDED select sql_calc_found_rows s_name, s_address from supplier, nation diff --git a/mysql-test/t/selectivity.test b/mysql-test/t/selectivity.test index 77089271cdd..5ec24d5f66e 100644 --- a/mysql-test/t/selectivity.test +++ b/mysql-test/t/selectivity.test @@ -31,6 +31,119 @@ customer, lineitem, nation, orders, part, partsupp, region, supplier; --enable_result_log --enable_query_log + +--echo === Q15 === + +create view revenue0 (supplier_no, total_revenue) as + select l_suppkey, sum(l_extendedprice * (1 - l_discount)) + from lineitem + where + l_shipdate >= '1995-08-01' + and l_shipdate < date_add('1995-08-01', interval 90 day) + group by l_suppkey; + +let $Q15= +select s_suppkey, s_name, s_address, s_phone, total_revenue +from supplier, revenue0 +where s_suppkey = supplier_no + and total_revenue = (select max(total_revenue) from revenue0) +order by s_suppkey; + +set @save_optimizer_switch=@@optimizer_switch; +set optimizer_switch='index_condition_pushdown=off'; + +set optimizer_use_condition_selectivity=1; +eval EXPLAIN EXTENDED $Q15; +eval $Q15; + +set optimizer_use_condition_selectivity=3; +eval EXPLAIN EXTENDED $Q15; +eval $Q15; + +set optimizer_switch=@save_optimizer_switch; + +drop view revenue0; + + +--echo === Q16 === + +let $Q16= +select p_brand, p_type, p_size, count(distinct ps_suppkey) as supplier_cnt +from partsupp, part +where p_partkey = ps_partkey + and p_brand <> 'Brand#11' + and p_type not like 'SMALL POLISHED%' + and p_size in (49, 37, 27, 5, 40, 6, 22, 8) + and ps_suppkey not in (select s_suppkey from supplier + where s_comment like '%Customer%Complaints%') +group by p_brand, p_type, p_size +order by supplier_cnt desc, p_brand, p_type, p_size; + +set optimizer_use_condition_selectivity=1; +eval EXPLAIN EXTENDED $Q16; +eval $Q16; + +set optimizer_use_condition_selectivity=3; +eval EXPLAIN EXTENDED $Q16; +eval $Q16; + +set optimizer_use_condition_selectivity=4; +eval EXPLAIN EXTENDED $Q16; +eval $Q16; + + +--echo === Q18 === + +let $Q18= +select + c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice, sum(l_quantity) +from customer, orders, lineitem +where + o_orderkey in (select l_orderkey from lineitem + group by l_orderkey having sum(l_quantity) > 250) + and c_custkey = o_custkey + and o_orderkey = l_orderkey +group by c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice +order by o_totalprice desc, o_orderdate; + +set optimizer_use_condition_selectivity=1; +eval EXPLAIN EXTENDED $Q18; +eval $Q18; + +set optimizer_use_condition_selectivity=3; +eval EXPLAIN EXTENDED $Q18; +eval $Q18; + + +--echo === Q22 === + +let $Q22= +select cntrycode, count(*) as numcust, sum(c_acctbal) as totacctbal +from ( + select substr(c_phone, 1, 2) as cntrycode, c_acctbal + from customer + where + substr(c_phone, 1, 2) in ('10', '20', '14', '19', '11', '28', '25') + and c_acctbal > (select avg(c_acctbal) from customer + where c_acctbal > 0.00 + and substr(c_phone, 1, 2) in + ('10', '20', '14', '19', '11', '28', '25')) + and not exists (select * from orders where o_custkey = c_custkey) + ) as vip +group by cntrycode +order by cntrycode; + +set optimizer_use_condition_selectivity=1; +eval EXPLAIN EXTENDED $Q22; +eval $Q22; + +set optimizer_use_condition_selectivity=3; +eval EXPLAIN EXTENDED $Q22; +eval $Q22; + + +--echo === Q20 === + let $Q20= select sql_calc_found_rows s_name, s_address @@ -51,11 +164,11 @@ and n_name = 'UNITED STATES' order by s_name limit 10; +set optimizer_use_condition_selectivity=1; eval EXPLAIN EXTENDED $Q20; eval $Q20; set optimizer_use_condition_selectivity=3; - eval EXPLAIN EXTENDED $Q20; eval $Q20; @@ -66,7 +179,6 @@ flush table part; ANALYZE TABLE part PERSISTENT FOR COLUMNS(p_name) INDEXES(); set optimizer_use_condition_selectivity=4; - eval EXPLAIN EXTENDED $Q20; eval $Q20; @@ -79,6 +191,7 @@ ANALYZE TABLE nation PERSISTENT FOR COLUMNS(n_name) INDEXES(); eval EXPLAIN EXTENDED $Q20; eval $Q20; + DROP DATABASE dbt3_s001; set histogram_size=@save_histogram_size; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a73760d4134..ddde1b3f358 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6878,7 +6878,8 @@ double JOIN::get_examined_rows() static double table_multi_eq_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, - table_map rem_tables, TABLE_REF *ref) + table_map rem_tables, uint keyparts, + uint16 *ref_keyuse_steps) { double sel= 1.0; COND_EQUAL *cond_equal= join->cond_equal; @@ -6886,15 +6887,15 @@ double table_multi_eq_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, if (!cond_equal || !cond_equal->current_level.elements) return sel; - Item_equal *item_equal; - List_iterator_fast<Item_equal> it(cond_equal->current_level); - table_map table_bit= s->table->map; - - if (!s->keyuse) + if (!s->keyuse) return sel; - KEY *key_info= s->get_keyinfo_by_key_no(s->ref.key); - + Item_equal *item_equal; + List_iterator_fast<Item_equal> it(cond_equal->current_level); + TABLE *table= s->table; + table_map table_bit= table->map; + POSITION *pos= &join->positions[idx]; + while ((item_equal= it++)) { /* @@ -6916,17 +6917,25 @@ double table_multi_eq_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, Field *fld= fi.get_curr_field(); if (fld->table->map != table_bit) continue; - if (ref == 0) + if (pos->key == 0) adjust_sel= TRUE; else { uint i; - for (i= 0; i < ref->key_parts; i++) + KEYUSE *keyuse= pos->key; + uint key= keyuse->key; + + for (i= 0; i < keyparts; i++) { - if (fld->field_index == key_info->key_part[i].fieldnr - 1) + uint fldno; + if (is_hash_join_key_no(key)) + fldno= keyuse->keypart; + else + fldno= table->key_info[key].key_part[keyparts-1].fieldnr - 1; + if (fld->field_index == fldno) break; } - if (i == ref->key_parts) + if (i == keyparts) { /* Field fld is included in multiple equality item_equal @@ -6936,11 +6945,14 @@ double table_multi_eq_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, equal to fld. */ adjust_sel= TRUE; - for (uint j= 0; j < ref->key_parts && adjust_sel; j++) + for (uint j= 0; j < keyparts && adjust_sel; j++) { - if (ref->items[j]->real_item()->type() == Item::FIELD_ITEM) + if (j > 0) + keyuse+= ref_keyuse_steps[j-1]; + Item *ref_item= keyuse->val; + if (ref_item->real_item()->type() == Item::FIELD_ITEM) { - Item_field *field_item= (Item_field *) (ref->items[j]); + Item_field *field_item= (Item_field *) ref_item; if (item_equal->contains(field_item->field)) adjust_sel= FALSE; } @@ -6978,33 +6990,70 @@ static double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, table_map rem_tables) { + uint16 ref_keyuse_steps[MAX_REF_PARTS - 1]; Field *field; TABLE *table= s->table; MY_BITMAP *read_set= table->read_set; double sel= s->table->cond_selectivity; double table_records= table->stat_records(); - TABLE_REF *ref= s->type == JT_REF || s->type == JT_EQ_REF ? &s->ref : NULL; + POSITION *pos= &join->positions[idx]; + uint keyparts= 0; + uint found_part_ref_or_null= 0; /* Discount the selectivity of the access method used to join table s */ if (s->quick && s->quick->index != MAX_KEY) { - if (join->positions[idx].key == 0) + if (pos->key == 0) { sel*= table->quick_rows[s->quick->index]/table_records; } } - else if (ref) + else if (pos->key != 0) { - /* A ref/ access or hash join is used to join table s */ - KEY *key_info= s->get_keyinfo_by_key_no(ref->key); - for (uint i= 0; i < ref->key_parts; i++) + /* A ref/ access or hash join is used to join table */ + KEYUSE *keyuse= pos->key; + KEYUSE *prev_ref_keyuse= keyuse; + uint key= keyuse->key; + do { - if (ref->items[i]->const_item()) + if (!(keyuse->used_tables & (rem_tables | table->map))) { - uint fldno= key_info->key_part[i].fieldnr - 1; - sel*= table->field[fldno]->cond_selectivity; + if (are_tables_local(s, keyuse->val->used_tables())) + { + if (is_hash_join_key_no(key)) + { + if (keyparts == keyuse->keypart) + keyparts++; + } + else + { + if (keyparts == keyuse->keypart && + !(~(keyuse->val->used_tables()) & pos->ref_depend_map) && + !(found_part_ref_or_null & keyuse->optimize)) + { + keyparts++; + found_part_ref_or_null|= keyuse->optimize & ~KEY_OPTIMIZE_EQ; + } + } + if (keyparts > keyuse->keypart) + { + uint fldno; + if (is_hash_join_key_no(key)) + fldno= keyuse->keypart; + else + fldno= table->key_info[key].key_part[keyparts-1].fieldnr - 1; + if (keyuse->val->const_item()) + sel*= table->field[fldno]->cond_selectivity; + if (keyparts > 1) + { + ref_keyuse_steps[keyparts-2]= keyuse - prev_ref_keyuse; + prev_ref_keyuse= keyuse; + } + } + } } - } + keyuse++; + } while (keyuse->table == table && keyuse->key == key); } for (Field **f_ptr=table->field ; (field= *f_ptr) ; f_ptr++) @@ -7024,7 +7073,8 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, } } - sel*= table_multi_eq_cond_selectivity(join, idx, s, rem_tables, ref); + sel*= table_multi_eq_cond_selectivity(join, idx, s, rem_tables, + keyparts, ref_keyuse_steps); return sel; } diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 8c0b2730b02..0f26ca7520a 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -3303,6 +3303,18 @@ double get_column_avg_frequency(Field * field) { double res; TABLE *table= field->table; + + /* + Statistics is shared by table instances and is accessed through + the table share. If table->s->field is not set for 'table', then + no column statistics is available for the table . + */ + if (!table->s->field) + { + res= table->stat_records(); + return res; + } + Column_statistics *col_stats= table->s->field[field->field_index]->read_stats; if (!col_stats) @@ -3323,8 +3335,8 @@ double get_column_range_cardinality(Field *field, 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)) + else if (min_endp && max_endp && min_endp->length == max_endp->length && + !memcmp(min_endp->key, max_endp->key, min_endp->length)) { double avg_frequency= col_stats->get_avg_frequency(); res= avg_frequency; @@ -3346,13 +3358,27 @@ double get_column_range_cardinality(Field *field, { if (col_stats->min_value && col_stats->max_value) { - double sel; - 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); + double sel, min_mp_pos, max_mp_pos; + + if (min_endp) + { + store_key_image_to_rec(field, (uchar *) min_endp->key, + min_endp->length); + min_mp_pos= field->middle_point_pos(col_stats->min_value, + col_stats->max_value); + } + else + min_mp_pos= 0.0; + if (max_endp) + { + store_key_image_to_rec(field, (uchar *) max_endp->key, + max_endp->length); + max_mp_pos= field->middle_point_pos(col_stats->min_value, + col_stats->max_value); + } + else + max_mp_pos= 1.0; + Histogram *hist= &col_stats->histogram; if (hist->get_size() == 0) sel= (max_mp_pos - min_mp_pos); diff --git a/sql/table.cc b/sql/table.cc index eb693170cb2..2adaf5b5bf7 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -3974,6 +3974,7 @@ void TABLE::init(THD *thd, TABLE_LIST *tl) file->ha_start_of_new_statement(); reginfo.impossible_range= 0; created= TRUE; + cond_selectivity= 1.0; /* Catch wrong handling of the auto_increment_field_not_null. */ DBUG_ASSERT(!auto_increment_field_not_null); @@ -3982,6 +3983,11 @@ void TABLE::init(THD *thd, TABLE_LIST *tl) pos_in_table_list= tl; clear_column_bitmaps(); + for (Field **f_ptr= field ; *f_ptr ; f_ptr++) + { + (*f_ptr)->next_equal_field= NULL; + (*f_ptr)->cond_selectivity= 1.0; + } DBUG_ASSERT(key_read == 0); |