Skip to content

Commit dae20dd

Browse files
committed
MDEV-26901: Estimation for filtered rows less precise ... #4
In Histogram_json_hb::point_selectivity(), do return selectivity of 0.0 when the histogram says so. The logic of "Do not return 0.0 estimate as it causes a multiply-by-zero meltdown in cost and cardinality calculations" is moved into records_in_column_ranges() where it is one *once* per column pair (as opposed to doing once per range, which can cause the error to add-up to large number when there are many ranges)
1 parent db8f15b commit dae20dd

File tree

6 files changed

+42
-6
lines changed

6 files changed

+42
-6
lines changed

mysql-test/main/selectivity.result

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,8 +1245,8 @@ EXPLAIN EXTENDED
12451245
SELECT * FROM language, country, continent
12461246
WHERE country_group = lang_group AND lang_group IS NULL;
12471247
id select_type table type possible_keys key key_len ref rows filtered Extra
1248-
1 SIMPLE country ALL NULL NULL NULL NULL 2 0.00 Using where
1249-
1 SIMPLE language ALL NULL NULL NULL NULL 6 0.00 Using where; Using join buffer (flat, BNL join)
1248+
1 SIMPLE country ALL NULL NULL NULL NULL 2 50.00 Using where
1249+
1 SIMPLE language ALL NULL NULL NULL NULL 6 16.67 Using where; Using join buffer (flat, BNL join)
12501250
1 SIMPLE continent ALL NULL NULL NULL NULL 6 100.00 Using join buffer (incremental, BNL join)
12511251
Warnings:
12521252
Note 1003 select `test`.`language`.`lang_group` AS `lang_group`,`test`.`language`.`lang` AS `lang`,`test`.`country`.`code` AS `code`,`test`.`country`.`country_group` AS `country_group`,`test`.`continent`.`cont_group` AS `cont_group`,`test`.`continent`.`cont` AS `cont` from `test`.`language` join `test`.`country` join `test`.`continent` where `test`.`language`.`lang_group` = `test`.`country`.`country_group` and `test`.`country`.`country_group` is null

mysql-test/main/selectivity_innodb.result

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,8 +1257,8 @@ EXPLAIN EXTENDED
12571257
SELECT * FROM language, country, continent
12581258
WHERE country_group = lang_group AND lang_group IS NULL;
12591259
id select_type table type possible_keys key key_len ref rows filtered Extra
1260-
1 SIMPLE country ALL NULL NULL NULL NULL 2 0.00 Using where
1261-
1 SIMPLE language ALL NULL NULL NULL NULL 6 0.00 Using where; Using join buffer (flat, BNL join)
1260+
1 SIMPLE country ALL NULL NULL NULL NULL 2 50.00 Using where
1261+
1 SIMPLE language ALL NULL NULL NULL NULL 6 16.67 Using where; Using join buffer (flat, BNL join)
12621262
1 SIMPLE continent ALL NULL NULL NULL NULL 6 100.00 Using join buffer (incremental, BNL join)
12631263
Warnings:
12641264
Note 1003 select `test`.`language`.`lang_group` AS `lang_group`,`test`.`language`.`lang` AS `lang`,`test`.`country`.`code` AS `code`,`test`.`country`.`country_group` AS `country_group`,`test`.`continent`.`cont_group` AS `cont_group`,`test`.`continent`.`cont` AS `cont` from `test`.`language` join `test`.`country` join `test`.`continent` where `test`.`language`.`lang_group` = `test`.`country`.`country_group` and `test`.`country`.`country_group` is null

mysql-test/main/statistics_json.result

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8264,3 +8264,23 @@ ANALYZE SELECT * FROM t1 WHERE f > '00:01:00';
82648264
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
82658265
1 SIMPLE t1 ALL NULL NULL NULL NULL 1000 1000.00 50.00 50.00 Using where
82668266
drop table t1;
8267+
#
8268+
# MDEV-26901: Estimation for filtered rows less precise ... #4
8269+
#
8270+
create table t1 (f int);
8271+
insert into t1 values
8272+
(7),(5),(0),(5),(112),(9),(9),(7),(5),(9),
8273+
(1),(7),(0),(6),(6),(2),(1),(6),(169),(7);
8274+
select f from t1 where f in (77, 1, 144, 73, 14, 12);
8275+
f
8276+
1
8277+
1
8278+
set histogram_type= JSON_HB;
8279+
analyze table t1 persistent for all;
8280+
Table Op Msg_type Msg_text
8281+
test.t1 analyze status Engine-independent statistics collected
8282+
test.t1 analyze status OK
8283+
analyze select f from t1 where f in (77, 1, 144, 73, 14, 12);
8284+
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
8285+
1 SIMPLE t1 ALL NULL NULL NULL NULL 20 20.00 10.00 10.00 Using where
8286+
drop table t1;

mysql-test/main/statistics_json.test

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,3 +429,19 @@ ANALYZE TABLE t1 PERSISTENT FOR ALL;
429429
ANALYZE SELECT * FROM t1 WHERE f > '00:01:00';
430430
drop table t1;
431431

432+
--echo #
433+
--echo # MDEV-26901: Estimation for filtered rows less precise ... #4
434+
--echo #
435+
create table t1 (f int);
436+
insert into t1 values
437+
(7),(5),(0),(5),(112),(9),(9),(7),(5),(9),
438+
(1),(7),(0),(6),(6),(2),(1),(6),(169),(7);
439+
440+
select f from t1 where f in (77, 1, 144, 73, 14, 12);
441+
442+
set histogram_type= JSON_HB;
443+
analyze table t1 persistent for all;
444+
445+
analyze select f from t1 where f in (77, 1, 144, 73, 14, 12);
446+
drop table t1;
447+

sql/opt_histogram_json.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -921,7 +921,7 @@ double Histogram_json_hb::point_selectivity(Field *field, key_range *endpoint,
921921
The bucket has a single value and it doesn't match! Return a very
922922
small value.
923923
*/
924-
sel= 1.0 / total_rows;
924+
sel= 0.0;
925925
}
926926
else
927927
{

sql/opt_range.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3279,7 +3279,7 @@ double records_in_column_ranges(PARAM *param, uint idx,
32793279
total_rows += rows;
32803280
}
32813281
if (total_rows == 0)
3282-
total_rows= MY_MIN(1, param->table->stat_records());
3282+
total_rows= MY_MIN(1, rows2double(param->table->stat_records()));
32833283

32843284
return total_rows;
32853285
}

0 commit comments

Comments
 (0)