summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/selectivity.result341
-rw-r--r--mysql-test/r/selectivity_innodb.result341
-rw-r--r--mysql-test/t/selectivity.test117
-rw-r--r--sql/sql_select.cc102
-rw-r--r--sql/sql_statistics.cc44
-rw-r--r--sql/table.cc6
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);