From bc9805e95432325b8d3d812e7cc4f6e1380d2345 Mon Sep 17 00:00:00 2001 From: Monty Date: Fri, 8 Oct 2021 01:40:59 +0300 Subject: [PATCH] Return >= 1 from matching_candidates_in_table if records > 0.0 Having rows >= 1.0 helps ensure that when we calculate total rows of joins the number of resulting rows will not be less after the join. Changes in test cases: - Join order change for some tables with few records - 'Filtered' is much higher for tables with few rows, as 1 row is a high procent of a table with few rows. --- mysql-test/main/join_nested_jcl6.result | 8 ++++---- mysql-test/main/opt_trace.result | 2 +- mysql-test/main/opt_trace_selectivity.result | 10 +++++----- mysql-test/main/range.result | 2 +- mysql-test/main/range_mrr_icp.result | 2 +- mysql-test/main/rowid_filter.result | 16 ++++++++-------- mysql-test/main/rowid_filter_innodb.result | 20 ++++++++++---------- mysql-test/main/rowid_filter_innodb.test | 1 + mysql-test/main/selectivity.result | 6 +++--- mysql-test/main/selectivity_innodb.result | 4 ++-- mysql-test/main/stat_tables.result | 2 +- mysql-test/main/stat_tables_innodb.result | 2 +- mysql-test/main/statistics_json.result | 2 +- sql/sql_select.cc | 12 +++++++++++- 14 files changed, 50 insertions(+), 39 deletions(-) diff --git a/mysql-test/main/join_nested_jcl6.result b/mysql-test/main/join_nested_jcl6.result index 0a5560bc849..57bd6298b3b 100644 --- a/mysql-test/main/join_nested_jcl6.result +++ b/mysql-test/main/join_nested_jcl6.result @@ -2120,9 +2120,9 @@ FROM t5 LEFT JOIN ON (t5.b=t8.b); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t5 ALL NULL NULL NULL NULL 2 -1 SIMPLE t8 ALL b_i NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join) -1 SIMPLE t6 ALL NULL NULL NULL NULL 1 Using join buffer (incremental, BNL join) +1 SIMPLE t6 ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join) 1 SIMPLE t7 const PRIMARY PRIMARY 4 const 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t8 ALL b_i NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join) SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b FROM t5 LEFT JOIN (t6 LEFT JOIN t7 ON t7.a=1, t8) @@ -2137,9 +2137,9 @@ FROM t5 LEFT JOIN ON (t5.b=t8.b); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t5 ALL NULL NULL NULL NULL 2 -1 SIMPLE t8 ALL b_i NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join) -1 SIMPLE t6 ALL NULL NULL NULL NULL 1 Using join buffer (incremental, BNL join) +1 SIMPLE t6 ALL NULL NULL NULL NULL 1 Using join buffer (flat, BNL join) 1 SIMPLE t7 ref b_i b_i 5 const 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t8 ALL b_i NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join) SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b FROM t5 LEFT JOIN (t6 LEFT JOIN t7 ON t7.b=2, t8) diff --git a/mysql-test/main/opt_trace.result b/mysql-test/main/opt_trace.result index e143d29215b..fe93ac44d99 100644 --- a/mysql-test/main/opt_trace.result +++ b/mysql-test/main/opt_trace.result @@ -9823,7 +9823,7 @@ test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK EXPLAIN EXTENDED SELECT * from t1 WHERE a between 1 and 5 and b <= 5; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 100 0.25 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 100 1.00 Using where Warnings: Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where `test`.`t1`.`a` between 1 and 5 and `test`.`t1`.`b` <= 5 select JSON_DETAILED(JSON_EXTRACT(trace, '$**.selectivity_for_columns')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE; diff --git a/mysql-test/main/opt_trace_selectivity.result b/mysql-test/main/opt_trace_selectivity.result index 0c493d37812..31eddaf5c10 100644 --- a/mysql-test/main/opt_trace_selectivity.result +++ b/mysql-test/main/opt_trace_selectivity.result @@ -160,16 +160,16 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) }, { "access_type": "index_merge", - "resulting_rows": 0.6, - "cost": 2.172957403, + "resulting_rows": 1, + "cost": 2.092957403, "chosen": true } ], "chosen_access_method": { "type": "index_merge", - "records": 0.6, - "cost": 2.172957403, + "records": 1, + "cost": 2.092957403, "uses_join_buffering": false } } @@ -180,7 +180,7 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) "plan_prefix": [], "table": "t1", - "rows_for_plan": 0.6, + "rows_for_plan": 1, "cost_for_plan": 2.292957403 } ] diff --git a/mysql-test/main/range.result b/mysql-test/main/range.result index 6ff4f409666..36e6e2b2aec 100644 --- a/mysql-test/main/range.result +++ b/mysql-test/main/range.result @@ -2765,7 +2765,7 @@ EXPLAIN "selectivity_pct": 6.730769231 }, "rows": 7, - "filtered": 6.730769157, + "filtered": 14.28571415, "index_condition": "t2.d is not null", "attached_condition": "(t2.d,t2.e) in (((4,4)),((7,7)),((8,8))) and octet_length(t2.f) = 1" } diff --git a/mysql-test/main/range_mrr_icp.result b/mysql-test/main/range_mrr_icp.result index c2c715a0a89..d2d06ab7b42 100644 --- a/mysql-test/main/range_mrr_icp.result +++ b/mysql-test/main/range_mrr_icp.result @@ -2749,7 +2749,7 @@ EXPLAIN "key_length": "5", "used_key_parts": ["d"], "rows": 7, - "filtered": 6.730769157, + "filtered": 14.28571415, "index_condition": "t2.d is not null", "attached_condition": "(t2.d,t2.e) in (((4,4)),((7,7)),((8,8))) and octet_length(t2.f) = 1", "mrr_type": "Rowid-ordered scan" diff --git a/mysql-test/main/rowid_filter.result b/mysql-test/main/rowid_filter.result index e07d80be41d..e86cff59bd3 100644 --- a/mysql-test/main/rowid_filter.result +++ b/mysql-test/main/rowid_filter.result @@ -1316,7 +1316,7 @@ EXPLAIN "key_length": "4", "used_key_parts": ["l_receiptDATE"], "rows": 18, - "filtered": 0.566194832, + "filtered": 5.555555344, "index_condition": "lineitem.l_receiptDATE between '1996-10-05' and '1996-10-10'", "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-10-10'" } @@ -1345,7 +1345,7 @@ l_shipdate BETWEEN '1996-10-01' AND '1996-10-10' AND l_receiptdate BETWEEN '1996-10-05' AND '1996-10-10' AND o_totalprice BETWEEN 200000 AND 250000; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra -1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_receiptdate,i_l_orderkey,i_l_orderkey_quantity i_l_receiptdate 4 NULL 18 18.00 0.57 38.89 Using index condition; Using where +1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_receiptdate,i_l_orderkey,i_l_orderkey_quantity i_l_receiptdate 4 NULL 18 18.00 5.56 38.89 Using index condition; Using where 1 SIMPLE orders eq_ref PRIMARY,i_o_totalprice PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 1.00 7.47 14.29 Using where set statement optimizer_switch='rowid_filter=on' for ANALYZE FORMAT=JSON SELECT l_shipdate, l_receiptdate, o_totalprice FROM orders, lineitem @@ -1382,7 +1382,7 @@ ANALYZE "r_rows": 18, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", - "filtered": 0.566194832, + "filtered": 5.555555344, "r_filtered": 38.88888889, "index_condition": "lineitem.l_receiptDATE between '1996-10-05' and '1996-10-10'", "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-10-10'" @@ -1453,7 +1453,7 @@ EXPLAIN "key_length": "4", "used_key_parts": ["l_receiptDATE"], "rows": 18, - "filtered": 0.566194832, + "filtered": 5.555555344, "index_condition": "lineitem.l_receiptDATE between '1996-10-05' and '1996-10-10'", "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-10-10'" } @@ -1482,7 +1482,7 @@ l_shipdate BETWEEN '1996-10-01' AND '1996-10-10' AND l_receiptdate BETWEEN '1996-10-05' AND '1996-10-10' AND o_totalprice BETWEEN 200000 AND 250000; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra -1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_receiptdate,i_l_orderkey,i_l_orderkey_quantity i_l_receiptdate 4 NULL 18 18.00 0.57 38.89 Using index condition; Using where +1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_receiptdate,i_l_orderkey,i_l_orderkey_quantity i_l_receiptdate 4 NULL 18 18.00 5.56 38.89 Using index condition; Using where 1 SIMPLE orders eq_ref PRIMARY,i_o_totalprice PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 1.00 7.47 14.29 Using where set statement optimizer_switch='rowid_filter=off' for ANALYZE FORMAT=JSON SELECT l_shipdate, l_receiptdate, o_totalprice FROM orders, lineitem @@ -1519,7 +1519,7 @@ ANALYZE "r_rows": 18, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", - "filtered": 0.566194832, + "filtered": 5.555555344, "r_filtered": 38.88888889, "index_condition": "lineitem.l_receiptDATE between '1996-10-05' and '1996-10-10'", "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-10-10'" @@ -2505,7 +2505,7 @@ ANALYZE "r_rows": 1, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", - "filtered": 49.20000076, + "filtered": 100, "r_filtered": 100, "index_condition": "t1.nm like '500%'", "attached_condition": "t1.fl2 = 0" @@ -2558,7 +2558,7 @@ ANALYZE "r_rows": 1, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", - "filtered": 49.20000076, + "filtered": 100, "r_filtered": 100, "index_condition": "t1.nm like '500%'", "attached_condition": "t1.fl2 = 0" diff --git a/mysql-test/main/rowid_filter_innodb.result b/mysql-test/main/rowid_filter_innodb.result index 8a464785195..51c061fe3a4 100644 --- a/mysql-test/main/rowid_filter_innodb.result +++ b/mysql-test/main/rowid_filter_innodb.result @@ -1306,7 +1306,7 @@ EXPLAIN "key_length": "4", "used_key_parts": ["l_receiptDATE"], "rows": 18, - "filtered": 0.566194832, + "filtered": 5.555555344, "index_condition": "lineitem.l_receiptDATE between '1996-10-05' and '1996-10-10'", "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-10-10'" } @@ -1335,7 +1335,7 @@ l_shipdate BETWEEN '1996-10-01' AND '1996-10-10' AND l_receiptdate BETWEEN '1996-10-05' AND '1996-10-10' AND o_totalprice BETWEEN 200000 AND 250000; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra -1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_receiptdate,i_l_orderkey,i_l_orderkey_quantity i_l_receiptdate 4 NULL 18 18.00 0.57 38.89 Using index condition; Using where +1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_receiptdate,i_l_orderkey,i_l_orderkey_quantity i_l_receiptdate 4 NULL 18 18.00 5.56 38.89 Using index condition; Using where 1 SIMPLE orders eq_ref PRIMARY,i_o_totalprice PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 1.00 5.67 14.29 Using where set statement optimizer_switch='rowid_filter=on' for ANALYZE FORMAT=JSON SELECT l_shipdate, l_receiptdate, o_totalprice FROM orders, lineitem @@ -1372,7 +1372,7 @@ ANALYZE "r_rows": 18, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", - "filtered": 0.566194832, + "filtered": 5.555555344, "r_filtered": 38.88888889, "index_condition": "lineitem.l_receiptDATE between '1996-10-05' and '1996-10-10'", "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-10-10'" @@ -1443,7 +1443,7 @@ EXPLAIN "key_length": "4", "used_key_parts": ["l_receiptDATE"], "rows": 18, - "filtered": 0.566194832, + "filtered": 5.555555344, "index_condition": "lineitem.l_receiptDATE between '1996-10-05' and '1996-10-10'", "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-10-10'" } @@ -1472,7 +1472,7 @@ l_shipdate BETWEEN '1996-10-01' AND '1996-10-10' AND l_receiptdate BETWEEN '1996-10-05' AND '1996-10-10' AND o_totalprice BETWEEN 200000 AND 250000; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra -1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_receiptdate,i_l_orderkey,i_l_orderkey_quantity i_l_receiptdate 4 NULL 18 18.00 0.57 38.89 Using index condition; Using where +1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_receiptdate,i_l_orderkey,i_l_orderkey_quantity i_l_receiptdate 4 NULL 18 18.00 5.56 38.89 Using index condition; Using where 1 SIMPLE orders eq_ref PRIMARY,i_o_totalprice PRIMARY 4 dbt3_s001.lineitem.l_orderkey 1 1.00 5.67 14.29 Using where set statement optimizer_switch='rowid_filter=off' for ANALYZE FORMAT=JSON SELECT l_shipdate, l_receiptdate, o_totalprice FROM orders, lineitem @@ -1509,7 +1509,7 @@ ANALYZE "r_rows": 18, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", - "filtered": 0.566194832, + "filtered": 5.555555344, "r_filtered": 38.88888889, "index_condition": "lineitem.l_receiptDATE between '1996-10-05' and '1996-10-10'", "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-10-10'" @@ -2495,7 +2495,7 @@ ANALYZE "r_rows": 1, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", - "filtered": 49.20000076, + "filtered": 100, "r_filtered": 100, "index_condition": "t1.nm like '500%'", "attached_condition": "t1.fl2 = 0" @@ -2548,7 +2548,7 @@ ANALYZE "r_rows": 1, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", - "filtered": 49.20000076, + "filtered": 100, "r_filtered": 100, "index_condition": "t1.nm like '500%'", "attached_condition": "t1.fl2 = 0" @@ -2967,8 +2967,8 @@ id y x 1 2 1 explain extended select * from t1 join t2 on t1.id = t2.x where t2.y = 2 and t1.id = 1; id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 100.00 Using index -1 SIMPLE t2 index_merge x,y y,x 5,5 NULL 1 100.00 Using intersect(y,x); Using where; Using index +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 # Using index +1 SIMPLE t2 index_merge x,y y,x 5,5 NULL 1 # Using intersect(y,x); Using where; Using index Warnings: Note 1003 select 1 AS `id`,`test`.`t2`.`y` AS `y`,`test`.`t2`.`x` AS `x` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`y` = 2 and `test`.`t2`.`x` = 1 drop table t1, t2; diff --git a/mysql-test/main/rowid_filter_innodb.test b/mysql-test/main/rowid_filter_innodb.test index 8705a0c9a12..339d4e37f67 100644 --- a/mysql-test/main/rowid_filter_innodb.test +++ b/mysql-test/main/rowid_filter_innodb.test @@ -70,6 +70,7 @@ let $q= select * from t1 join t2 on t1.id = t2.x where t2.y = 2 and t1.id = 1; eval $q; +--replace_column 10 # eval explain extended $q; drop table t1, t2; diff --git a/mysql-test/main/selectivity.result b/mysql-test/main/selectivity.result index 4ccad6c376f..e14bad43be9 100644 --- a/mysql-test/main/selectivity.result +++ b/mysql-test/main/selectivity.result @@ -72,18 +72,18 @@ and r_name = 'ASIA' order by s_acctbal desc, n_name, s_name, p_partkey; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 0.31 Using where; Using temporary; Using filesort +1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 0.50 Using where; Using temporary; Using filesort +1 PRIMARY region ALL PRIMARY NULL NULL NULL 5 20.00 Using where; Using join buffer (flat, BNL join) 1 PRIMARY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey i_ps_partkey 4 dbt3_s001.part.p_partkey 3 100.00 Using where 1 PRIMARY supplier eq_ref PRIMARY,i_s_nationkey PRIMARY 4 dbt3_s001.partsupp.ps_suppkey 1 100.00 Using where 1 PRIMARY nation eq_ref PRIMARY,i_n_regionkey PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 100.00 Using where -1 PRIMARY region eq_ref PRIMARY PRIMARY 4 dbt3_s001.nation.n_regionkey 1 20.00 Using where 2 DEPENDENT SUBQUERY region ALL PRIMARY NULL NULL NULL 5 20.00 Using where 2 DEPENDENT SUBQUERY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey i_ps_partkey 4 dbt3_s001.part.p_partkey 3 100.00 2 DEPENDENT SUBQUERY supplier eq_ref PRIMARY,i_s_nationkey PRIMARY 4 dbt3_s001.partsupp.ps_suppkey 1 100.00 Using where 2 DEPENDENT SUBQUERY nation eq_ref PRIMARY,i_n_regionkey PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 100.00 Using where Warnings: Note 1276 Field or reference 'dbt3_s001.part.p_partkey' of SELECT #2 was resolved in SELECT #1 -Note 1003 /* select#1 */ select `dbt3_s001`.`supplier`.`s_acctbal` AS `s_acctbal`,`dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`nation`.`n_name` AS `n_name`,`dbt3_s001`.`part`.`p_partkey` AS `p_partkey`,`dbt3_s001`.`part`.`p_mfgr` AS `p_mfgr`,`dbt3_s001`.`supplier`.`s_address` AS `s_address`,`dbt3_s001`.`supplier`.`s_phone` AS `s_phone`,`dbt3_s001`.`supplier`.`s_comment` AS `s_comment` from `dbt3_s001`.`part` join `dbt3_s001`.`supplier` join `dbt3_s001`.`partsupp` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where `dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey` and `dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`part`.`p_size` = 9 and `dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey` and `dbt3_s001`.`region`.`r_regionkey` = `dbt3_s001`.`nation`.`n_regionkey` and `dbt3_s001`.`region`.`r_name` = 'ASIA' and `dbt3_s001`.`part`.`p_type` like '%TIN' and `dbt3_s001`.`partsupp`.`ps_supplycost` = <`dbt3_s001`.`part`.`p_partkey`>((/* select#2 */ select min(`dbt3_s001`.`partsupp`.`ps_supplycost`) from `dbt3_s001`.`partsupp` join `dbt3_s001`.`supplier` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where `dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey` and `dbt3_s001`.`nation`.`n_regionkey` = `dbt3_s001`.`region`.`r_regionkey` and `dbt3_s001`.`region`.`r_name` = 'ASIA' and `dbt3_s001`.`part`.`p_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey`)) order by `dbt3_s001`.`supplier`.`s_acctbal` desc,`dbt3_s001`.`nation`.`n_name`,`dbt3_s001`.`supplier`.`s_name`,`dbt3_s001`.`part`.`p_partkey` +Note 1003 /* select#1 */ select `dbt3_s001`.`supplier`.`s_acctbal` AS `s_acctbal`,`dbt3_s001`.`supplier`.`s_name` AS `s_name`,`dbt3_s001`.`nation`.`n_name` AS `n_name`,`dbt3_s001`.`part`.`p_partkey` AS `p_partkey`,`dbt3_s001`.`part`.`p_mfgr` AS `p_mfgr`,`dbt3_s001`.`supplier`.`s_address` AS `s_address`,`dbt3_s001`.`supplier`.`s_phone` AS `s_phone`,`dbt3_s001`.`supplier`.`s_comment` AS `s_comment` from `dbt3_s001`.`part` join `dbt3_s001`.`supplier` join `dbt3_s001`.`partsupp` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where `dbt3_s001`.`partsupp`.`ps_partkey` = `dbt3_s001`.`part`.`p_partkey` and `dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`part`.`p_size` = 9 and `dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey` and `dbt3_s001`.`nation`.`n_regionkey` = `dbt3_s001`.`region`.`r_regionkey` and `dbt3_s001`.`region`.`r_name` = 'ASIA' and `dbt3_s001`.`part`.`p_type` like '%TIN' and `dbt3_s001`.`partsupp`.`ps_supplycost` = <`dbt3_s001`.`part`.`p_partkey`>((/* select#2 */ select min(`dbt3_s001`.`partsupp`.`ps_supplycost`) from `dbt3_s001`.`partsupp` join `dbt3_s001`.`supplier` join `dbt3_s001`.`nation` join `dbt3_s001`.`region` where `dbt3_s001`.`supplier`.`s_suppkey` = `dbt3_s001`.`partsupp`.`ps_suppkey` and `dbt3_s001`.`nation`.`n_nationkey` = `dbt3_s001`.`supplier`.`s_nationkey` and `dbt3_s001`.`nation`.`n_regionkey` = `dbt3_s001`.`region`.`r_regionkey` and `dbt3_s001`.`region`.`r_name` = 'ASIA' and `dbt3_s001`.`part`.`p_partkey` = `dbt3_s001`.`partsupp`.`ps_partkey`)) order by `dbt3_s001`.`supplier`.`s_acctbal` desc,`dbt3_s001`.`nation`.`n_name`,`dbt3_s001`.`supplier`.`s_name`,`dbt3_s001`.`part`.`p_partkey` set optimizer_use_condition_selectivity=4; explain extended select diff --git a/mysql-test/main/selectivity_innodb.result b/mysql-test/main/selectivity_innodb.result index 5a4281395ed..2371cfa111c 100644 --- a/mysql-test/main/selectivity_innodb.result +++ b/mysql-test/main/selectivity_innodb.result @@ -77,8 +77,8 @@ and r_name = 'ASIA' order by s_acctbal desc, n_name, s_name, p_partkey; id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 0.31 Using where; Using temporary; Using filesort -1 PRIMARY region ALL PRIMARY NULL NULL NULL 5 20.00 Using where; Using join buffer (flat, BNL join) +1 PRIMARY region ALL PRIMARY NULL NULL NULL 5 20.00 Using where; Using temporary; Using filesort +1 PRIMARY part ALL PRIMARY NULL NULL NULL 200 0.50 Using where; Using join buffer (flat, BNL join) 1 PRIMARY partsupp ref PRIMARY,i_ps_partkey,i_ps_suppkey PRIMARY 4 dbt3_s001.part.p_partkey 3 100.00 Using where 1 PRIMARY supplier eq_ref PRIMARY,i_s_nationkey PRIMARY 4 dbt3_s001.partsupp.ps_suppkey 1 100.00 Using where 1 PRIMARY nation eq_ref PRIMARY,i_n_regionkey PRIMARY 4 dbt3_s001.supplier.s_nationkey 1 100.00 Using where diff --git a/mysql-test/main/stat_tables.result b/mysql-test/main/stat_tables.result index e4165792f4a..dd6251edcd5 100644 --- a/mysql-test/main/stat_tables.result +++ b/mysql-test/main/stat_tables.result @@ -900,7 +900,7 @@ test t1 b 2 10 0.0000 4.0000 1.1111 0 NULL NULL analyze select * from t1 where a=1 and b=3; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 10 10.00 2.78 10.00 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 10 10.00 10.00 10.00 Using where drop table t1; set @@global.histogram_size=@save_histogram_size; # End of 10.4 tests diff --git a/mysql-test/main/stat_tables_innodb.result b/mysql-test/main/stat_tables_innodb.result index 13f990ed54f..732300e70e1 100644 --- a/mysql-test/main/stat_tables_innodb.result +++ b/mysql-test/main/stat_tables_innodb.result @@ -932,7 +932,7 @@ test t1 b 2 10 0.0000 4.0000 1.1111 0 NULL NULL analyze select * from t1 where a=1 and b=3; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 10 10.00 2.78 10.00 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 10 10.00 10.00 10.00 Using where drop table t1; set @@global.histogram_size=@save_histogram_size; # End of 10.4 tests diff --git a/mysql-test/main/statistics_json.result b/mysql-test/main/statistics_json.result index 748287152b1..375ed45afbc 100644 --- a/mysql-test/main/statistics_json.result +++ b/mysql-test/main/statistics_json.result @@ -4643,7 +4643,7 @@ Warnings: Note 1003 select `test`.`t1_json`.`a` AS `a` from `test`.`t1_json` where `test`.`t1_json`.`a` < 'b-1a' analyze select * from t1_json where a > 'zzzzzzzzz'; id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra -1 SIMPLE t1_json ALL NULL NULL NULL NULL 10 10.00 0.00 0.00 Using where +1 SIMPLE t1_json ALL NULL NULL NULL NULL 10 10.00 10.00 0.00 Using where drop table ten; UPDATE mysql.column_stats SET histogram='["not-what-you-expect"]' WHERE table_name='t1_json'; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 2f7b2dec729..3c443b56317 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7777,7 +7777,17 @@ static double matching_candidates_in_table(JOIN_TAB *s, if (with_found_constraint) dbl_records-= dbl_records/4; - return dbl_records; + + /* + Ensure we return at least one row if there is any possibility to have + a matching row. Having rows >= 1.0 helps ensure that when we calculate + total rows of joins, the number of resulting rows will not be less + after the join. In other words, we assume there is at least one matching + row when joining a row with the next table. + 0.0 is returned only if it is guaranteed there are no matching rows + (for example if the table is empty). + */ + return dbl_records ? MY_MAX(dbl_records, 1.0) : 0.0; }