You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Bug#33935417: Histograms cause zero row estimates for values outside histogram buckets
Histograms in MySQL return a selectivity estimate of zero for values
that are outside of buckets. Values can be missing from the histogram
because they were missed during sampling, or because the histogram has
grown stale.
This patch introduces a constant lower bound of 0.001 on the selectivity
estimates produced by histograms. This choice of lower bound corresponds
to the selectivity of a value/range that we are likely to miss during
sampling.
Using a constant lower bound rather than a statistical estimate for the
selectivity of a missing value has the advantage of simplicity and
predictability. It also provides some protection against underestimating
the selectivity due to stale histograms and within-bucket heuristics.
Change-Id: I94dceaf65995fce618abd01bc9ee80c1ffac677a
Signed-off-by: Jan Wedvik <jan.wedvik@oracle.com>
# Bug#33935417 Histograms cause zero row estimates for values outside
3893
+
# histogram buckets
3894
+
#
3895
+
CREATE TABLE ten (x INT);
3896
+
INSERT INTO ten VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);
3897
+
CREATE TABLE hundred (x INT);
3898
+
INSERT INTO hundred SELECT 10*ten1.x + ten0.x AS v
3899
+
FROM ten AS ten1, ten AS ten0 ORDER BY v;
3900
+
CREATE TABLE ten_thousand (x INT);
3901
+
INSERT INTO ten_thousand SELECT 100*h1.x + h0.x AS v
3902
+
FROM hundred AS h1, hundred AS h0 ORDER BY v;
3903
+
EXPLAIN SELECT * FROM ten WHERE x = -1;
3904
+
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
3905
+
1 SIMPLE ten NULL ALL NULL NULL NULL NULL 10 10.00 Using where
3906
+
Warnings:
3907
+
Note 1003 /* select#1 */ select `test`.`ten`.`x` AS `x` from `test`.`ten` where (`test`.`ten`.`x` = <cache>(-(1)))
3908
+
EXPLAIN SELECT * FROM hundred WHERE x = -1;
3909
+
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
3910
+
1 SIMPLE hundred NULL ALL NULL NULL NULL NULL 100 10.00 Using where
3911
+
Warnings:
3912
+
Note 1003 /* select#1 */ select `test`.`hundred`.`x` AS `x` from `test`.`hundred` where (`test`.`hundred`.`x` = <cache>(-(1)))
3913
+
EXPLAIN SELECT * FROM ten_thousand WHERE x = -1;
3914
+
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
3915
+
1 SIMPLE ten_thousand NULL ALL NULL NULL NULL NULL 10000 10.00 Using where
3916
+
Warnings:
3917
+
Note 1003 /* select#1 */ select `test`.`ten_thousand`.`x` AS `x` from `test`.`ten_thousand` where (`test`.`ten_thousand`.`x` = <cache>(-(1)))
3918
+
ANALYZE TABLE ten UPDATE HISTOGRAM ON x;
3919
+
Table Op Msg_type Msg_text
3920
+
test.ten histogram status Histogram statistics created for column 'x'.
3921
+
ANALYZE TABLE ten;
3922
+
Table Op Msg_type Msg_text
3923
+
test.ten analyze status OK
3924
+
ANALYZE TABLE hundred UPDATE HISTOGRAM ON x;
3925
+
Table Op Msg_type Msg_text
3926
+
test.hundred histogram status Histogram statistics created for column 'x'.
3927
+
ANALYZE TABLE hundred;
3928
+
Table Op Msg_type Msg_text
3929
+
test.hundred analyze status OK
3930
+
ANALYZE TABLE ten_thousand UPDATE HISTOGRAM ON x;
3931
+
Table Op Msg_type Msg_text
3932
+
test.ten_thousand histogram status Histogram statistics created for column 'x'.
3933
+
ANALYZE TABLE ten_thousand;
3934
+
Table Op Msg_type Msg_text
3935
+
test.ten_thousand analyze status OK
3936
+
EXPLAIN SELECT * FROM ten WHERE x = -1;
3937
+
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
3938
+
1 SIMPLE ten NULL ALL NULL NULL NULL NULL 10 10.00 Using where
3939
+
Warnings:
3940
+
Note 1003 /* select#1 */ select `test`.`ten`.`x` AS `x` from `test`.`ten` where (`test`.`ten`.`x` = <cache>(-(1)))
3941
+
EXPLAIN SELECT * FROM hundred WHERE x = -1;
3942
+
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
3943
+
1 SIMPLE hundred NULL ALL NULL NULL NULL NULL 100 1.00 Using where
3944
+
Warnings:
3945
+
Note 1003 /* select#1 */ select `test`.`hundred`.`x` AS `x` from `test`.`hundred` where (`test`.`hundred`.`x` = <cache>(-(1)))
3946
+
EXPLAIN SELECT * FROM ten_thousand WHERE x = -1;
3947
+
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
3948
+
1 SIMPLE ten_thousand NULL ALL NULL NULL NULL NULL 9980 0.10 Using where
3949
+
Warnings:
3950
+
Note 1003 /* select#1 */ select `test`.`ten_thousand`.`x` AS `x` from `test`.`ten_thousand` where (`test`.`ten_thousand`.`x` = <cache>(-(1)))
3951
+
EXPLAIN SELECT * FROM ten_thousand WHERE x < -1;
3952
+
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
3953
+
1 SIMPLE ten_thousand NULL ALL NULL NULL NULL NULL 9980 0.10 Using where
3954
+
Warnings:
3955
+
Note 1003 /* select#1 */ select `test`.`ten_thousand`.`x` AS `x` from `test`.`ten_thousand` where (`test`.`ten_thousand`.`x` < <cache>(-(1)))
3956
+
EXPLAIN SELECT * FROM ten_thousand WHERE x BETWEEN -100 AND -1;
3957
+
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
3958
+
1 SIMPLE ten_thousand NULL ALL NULL NULL NULL NULL 9980 0.10 Using where
3959
+
Warnings:
3960
+
Note 1003 /* select#1 */ select `test`.`ten_thousand`.`x` AS `x` from `test`.`ten_thousand` where (`test`.`ten_thousand`.`x` between <cache>(-(100)) and <cache>(-(1)))
3961
+
EXPLAIN SELECT * FROM ten_thousand WHERE x IN (-2, -1);
3962
+
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
3963
+
1 SIMPLE ten_thousand NULL ALL NULL NULL NULL NULL 9980 0.10 Using where
3964
+
Warnings:
3965
+
Note 1003 /* select#1 */ select `test`.`ten_thousand`.`x` AS `x` from `test`.`ten_thousand` where (`test`.`ten_thousand`.`x` in (<cache>(-(2)),<cache>(-(1))))
3966
+
EXPLAIN SELECT * FROM ten_thousand WHERE x IN (1, 2, 3);
3967
+
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
3968
+
1 SIMPLE ten_thousand NULL ALL NULL NULL NULL NULL 9980 0.10 Using where
3969
+
Warnings:
3970
+
Note 1003 /* select#1 */ select `test`.`ten_thousand`.`x` AS `x` from `test`.`ten_thousand` where (`test`.`ten_thousand`.`x` in (1,2,3))
0 commit comments