|
| 1 | +SET @session_start_value = @@new_mode; |
| 2 | +# Small driving table |
| 3 | +CREATE TABLE t1 (a INT, b INT); |
| 4 | +INSERT INTO t1 VALUES (1, 1), (2, 2000),(3,300); |
| 5 | +ANALYZE TABLE t1 PERSISTENT FOR ALL; |
| 6 | +Table Op Msg_type Msg_text |
| 7 | +test.t1 analyze status Engine-independent statistics collected |
| 8 | +test.t1 analyze status OK |
| 9 | +# Table that will be accessed by an index lookup (`ref` access) |
| 10 | +CREATE TABLE t2 (a INT, b INT, KEY key_b(b)); |
| 11 | +# All t11.b values are NULL |
| 12 | +INSERT INTO t2 SELECT seq/100, NULL FROM seq_1_to_1000; |
| 13 | +ANALYZE TABLE t2 PERSISTENT FOR ALL; |
| 14 | +Table Op Msg_type Msg_text |
| 15 | +test.t2 analyze status Engine-independent statistics collected |
| 16 | +test.t2 analyze status Table is already up to date |
| 17 | +SET @@new_mode = "FIX_INDEX_STATS_FOR_ALL_NULLS"; |
| 18 | +# NULL-rejecting equality t1.b = t2.b will not return any matches |
| 19 | +# because all values of t2.b are NULL. So "rows" = 1 for t2 where 1 is |
| 20 | +# a special value meaning "very few" rows |
| 21 | +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t2 ON t1.a = t2.a AND t1.b = t2.b; |
| 22 | +id select_type table type possible_keys key key_len ref rows filtered Extra |
| 23 | +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where |
| 24 | +1 SIMPLE t2 ref key_b key_b 5 test.t1.b 1 100.00 Using where |
| 25 | +Warnings: |
| 26 | +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a` and `test`.`t2`.`b` = `test`.`t1`.`b` |
| 27 | +# However, rows estimation for not NULL-rejecting conditions |
| 28 | +# must not be affected ("rows" > 1 is expected) |
| 29 | +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t2 ON t1.a = t2.a AND t1.b <=> t2.b; |
| 30 | +id select_type table type possible_keys key key_len ref rows filtered Extra |
| 31 | +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 |
| 32 | +1 SIMPLE t2 ref key_b key_b 5 test.t1.b 11 100.00 Using index condition; Using where |
| 33 | +Warnings: |
| 34 | +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a` and `test`.`t1`.`b` <=> `test`.`t2`.`b` |
| 35 | +# Insert some non-NULL values and re-collect the stats |
| 36 | +INSERT INTO t2 SELECT 1, 1 FROM seq_1_to_100; |
| 37 | +ANALYZE TABLE t2 PERSISTENT FOR COLUMNS (b) INDEXES (key_b); |
| 38 | +Table Op Msg_type Msg_text |
| 39 | +test.t2 analyze status Engine-independent statistics collected |
| 40 | +test.t2 analyze status OK |
| 41 | +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t2 ON t1.a = t2.a AND t1.b = t2.b; |
| 42 | +id select_type table type possible_keys key key_len ref rows filtered Extra |
| 43 | +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where |
| 44 | +1 SIMPLE t2 ref key_b key_b 5 test.t1.b 100 100.00 Using where |
| 45 | +Warnings: |
| 46 | +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a` and `test`.`t2`.`b` = `test`.`t1`.`b` |
| 47 | +# Test composite index for two columns. Key prefix is used for access |
| 48 | +CREATE TABLE t3 (a INT, b INT, KEY key_ab(a,b)); |
| 49 | +# All t3.b values are NULL |
| 50 | +INSERT INTO t3 SELECT seq/100, NULL FROM seq_1_to_1000; |
| 51 | +ANALYZE TABLE t3 PERSISTENT FOR COLUMNS(b) INDEXES(key_ab); |
| 52 | +Table Op Msg_type Msg_text |
| 53 | +test.t3 analyze status Engine-independent statistics collected |
| 54 | +test.t3 analyze status Table is already up to date |
| 55 | +# NULL-rejecting equality t1.b = t3.b, same as above. |
| 56 | +# "rows" must be estimated to 1 |
| 57 | +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a AND t1.b = t3.b; |
| 58 | +id select_type table type possible_keys key key_len ref rows filtered Extra |
| 59 | +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where |
| 60 | +1 SIMPLE t3 ref key_ab key_ab 10 test.t1.a,test.t1.b 1 100.00 Using index |
| 61 | +Warnings: |
| 62 | +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` join `test`.`t3` where `test`.`t3`.`a` = `test`.`t1`.`a` and `test`.`t3`.`b` = `test`.`t1`.`b` |
| 63 | +# Rows estimation for not NULL-rejecting conditions are not affected |
| 64 | +# ("rows" > 1 is expected) |
| 65 | +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a; |
| 66 | +id select_type table type possible_keys key key_len ref rows filtered Extra |
| 67 | +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where |
| 68 | +1 SIMPLE t3 ref key_ab key_ab 5 test.t1.a 90 100.00 Using index |
| 69 | +Warnings: |
| 70 | +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` join `test`.`t3` where `test`.`t3`.`a` = `test`.`t1`.`a` |
| 71 | +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a AND t1.b <=> t3.b; |
| 72 | +id select_type table type possible_keys key key_len ref rows filtered Extra |
| 73 | +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where |
| 74 | +1 SIMPLE t3 ref key_ab key_ab 10 test.t1.a,test.t1.b 11 100.00 Using where; Using index |
| 75 | +Warnings: |
| 76 | +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` join `test`.`t3` where `test`.`t3`.`a` = `test`.`t1`.`a` and `test`.`t1`.`b` <=> `test`.`t3`.`b` |
| 77 | +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a AND t3.b is NULL; |
| 78 | +id select_type table type possible_keys key key_len ref rows filtered Extra |
| 79 | +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where |
| 80 | +1 SIMPLE t3 ref key_ab key_ab 10 test.t1.a,const 11 100.00 Using where; Using index |
| 81 | +Warnings: |
| 82 | +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` join `test`.`t3` where `test`.`t3`.`a` = `test`.`t1`.`a` and `test`.`t3`.`b` is null |
| 83 | +# In the old mode (null-aware estimation is not enabled), "rows" > 1 |
| 84 | +SET @@new_mode = ""; |
| 85 | +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t2 ON t1.a = t2.a AND t1.b = t2.b; |
| 86 | +id select_type table type possible_keys key key_len ref rows filtered Extra |
| 87 | +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where |
| 88 | +1 SIMPLE t2 ref key_b key_b 5 test.t1.b 100 100.00 Using where |
| 89 | +Warnings: |
| 90 | +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a` and `test`.`t2`.`b` = `test`.`t1`.`b` |
| 91 | +# Insert some non-NULL values and re-collect the stats |
| 92 | +INSERT INTO t3 SELECT 1, 1 FROM seq_1_to_100; |
| 93 | +ANALYZE TABLE t3 PERSISTENT FOR COLUMNS (b) INDEXES (key_ab); |
| 94 | +Table Op Msg_type Msg_text |
| 95 | +test.t3 analyze status Engine-independent statistics collected |
| 96 | +test.t3 analyze status OK |
| 97 | +SET @@new_mode = "FIX_INDEX_STATS_FOR_ALL_NULLS"; |
| 98 | +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a AND t1.b = t3.b; |
| 99 | +id select_type table type possible_keys key key_len ref rows filtered Extra |
| 100 | +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where |
| 101 | +1 SIMPLE t3 ref key_ab key_ab 10 test.t1.a,test.t1.b 100 100.00 Using index |
| 102 | +Warnings: |
| 103 | +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` join `test`.`t3` where `test`.`t3`.`a` = `test`.`t1`.`a` and `test`.`t3`.`b` = `test`.`t1`.`b` |
| 104 | +# Test composite index for 3 columns. Key prefix is used for access |
| 105 | +CREATE TABLE t4 (a INT, b INT, c INT, KEY key_abc(a,b,c)); |
| 106 | +# All t3.b values are NULL |
| 107 | +INSERT INTO t4 SELECT seq/10, NULL, seq/10 FROM seq_1_to_1000; |
| 108 | +ANALYZE TABLE t4 PERSISTENT FOR COLUMNS(b) INDEXES(key_abc); |
| 109 | +Table Op Msg_type Msg_text |
| 110 | +test.t4 analyze status Engine-independent statistics collected |
| 111 | +test.t4 analyze status Table is already up to date |
| 112 | +# NULL-rejecting equality t1.b = t3.b, same as above. |
| 113 | +# "rows" must be estimated to 1 |
| 114 | +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t4 ON t1.a = t4.a AND t1.b = t4.b; |
| 115 | +id select_type table type possible_keys key key_len ref rows filtered Extra |
| 116 | +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where |
| 117 | +1 SIMPLE t4 ref key_abc key_abc 10 test.t1.a,test.t1.b 1 100.00 Using index |
| 118 | +Warnings: |
| 119 | +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c` from `test`.`t1` join `test`.`t4` where `test`.`t4`.`a` = `test`.`t1`.`a` and `test`.`t4`.`b` = `test`.`t1`.`b` |
| 120 | +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t4 ON t1.a = t4.a AND t1.b = t4.b and t1.b = t4.c; |
| 121 | +id select_type table type possible_keys key key_len ref rows filtered Extra |
| 122 | +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where |
| 123 | +1 SIMPLE t4 ref key_abc key_abc 15 test.t1.a,test.t1.b,test.t1.b 1 100.00 Using index |
| 124 | +Warnings: |
| 125 | +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c` from `test`.`t1` join `test`.`t4` where `test`.`t4`.`a` = `test`.`t1`.`a` and `test`.`t4`.`b` = `test`.`t1`.`b` and `test`.`t4`.`c` = `test`.`t1`.`b` |
| 126 | +# "rows" expected to be > 1 |
| 127 | +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t4 ON t1.a = t4.a; |
| 128 | +id select_type table type possible_keys key key_len ref rows filtered Extra |
| 129 | +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where |
| 130 | +1 SIMPLE t4 ref key_abc key_abc 5 test.t1.a 9 100.00 Using index |
| 131 | +Warnings: |
| 132 | +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c` from `test`.`t1` join `test`.`t4` where `test`.`t4`.`a` = `test`.`t1`.`a` |
| 133 | +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t4 ON t1.a = t4.a AND t1.b <=> t4.c; |
| 134 | +id select_type table type possible_keys key key_len ref rows filtered Extra |
| 135 | +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where |
| 136 | +1 SIMPLE t4 ref key_abc key_abc 5 test.t1.a 9 100.00 Using where; Using index |
| 137 | +Warnings: |
| 138 | +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c` from `test`.`t1` join `test`.`t4` where `test`.`t4`.`a` = `test`.`t1`.`a` and `test`.`t1`.`b` <=> `test`.`t4`.`c` |
| 139 | +DROP TABLE t1, t2, t3, t4; |
| 140 | +# Test for partially covered column |
| 141 | +CREATE TABLE t1 (a VARCHAR(10)); |
| 142 | +INSERT INTO t1 SELECT seq FROM seq_1_to_10; |
| 143 | +CREATE TABLE t2 ( |
| 144 | +a VARCHAR(10), |
| 145 | +b VARCHAR(10), |
| 146 | +INDEX i1(a, b(5)) |
| 147 | +); |
| 148 | +INSERT INTO t2 SELECT seq, NULL FROM seq_1_to_1000; |
| 149 | +ANALYZE TABLE t2 PERSISTENT FOR COLUMNS (b) INDEXES (i1); |
| 150 | +Table Op Msg_type Msg_text |
| 151 | +test.t2 analyze status Engine-independent statistics collected |
| 152 | +test.t2 analyze status Table is already up to date |
| 153 | +EXPLAIN SELECT * FROM t1, t2 WHERE t2.a=t1.a AND t2.b=t1.a; |
| 154 | +id select_type table type possible_keys key key_len ref rows Extra |
| 155 | +1 SIMPLE t1 ALL NULL NULL NULL NULL 10 Using where |
| 156 | +1 SIMPLE t2 ref i1 i1 66 test.t1.a,test.t1.a 1 Using where |
| 157 | +SET @@new_mode = @session_start_value; |
| 158 | +DROP TABLE t1, t2; |
0 commit comments