|
| 1 | +--enable_prepare_warnings |
| 2 | +--disable_view_protocol # Since optimizer hints are not supported inside views |
| 3 | + |
| 4 | +CREATE TABLE t1 (a INT, b VARCHAR(10), c VARCHAR(100), d VARCHAR(200), |
| 5 | + KEY key_a(a), KEY key_b(b), KEY key_c(c), KEY key_d(d)); |
| 6 | + |
| 7 | +INSERT INTO t1 VALUES |
| 8 | + (1,'w','z','F'), (1,'X','o','s'), (1,'q','c','a'), (5,'w','c','d'), (2,'j','m','k'), |
| 9 | + (2,'Q','s','q'), (9,'e','J','B'), (2,'p','W','l'), (9,'o','F','Y'), (2,'g','S','M'), |
| 10 | + (1,'Y','a','h'), (NULL,'Y','p','J'), (NULL,'s','x','M'), (NULL,'i','S','k'), |
| 11 | + (1,'l','q','w'), (7,'r','e','_'), (4,'b','h','I'), (NULL,'E','c','z'), |
| 12 | + (NULL,'M','a','j'), (3,'e','X','K'), (NULL,'p','r','R'), (9,'e','i','g'), |
| 13 | + (3,'g','x','m'), (2,'h','y','p'); |
| 14 | + |
| 15 | +ANALYZE TABLE t1; |
| 16 | + |
| 17 | +set optimizer_switch='rowid_filter=on'; |
| 18 | +--echo # range|filter `key_d|key_b` is applied by default when there are no hints: |
| 19 | +EXPLAIN EXTENDED |
| 20 | +SELECT a FROM t1 WHERE c < 'e' AND b > 't' and d < 'e'; |
| 21 | + |
| 22 | +--echo # Sample result set to compare against later |
| 23 | +SELECT a FROM t1 WHERE c < 'e' AND b > 't' and d < 'e'; |
| 24 | + |
| 25 | +--echo # Disable rowid filter for t1 |
| 26 | +EXPLAIN EXTENDED |
| 27 | +SELECT /*+ no_rowid_filter(t1)*/ a FROM t1 WHERE c < 'e' AND b > 't'; |
| 28 | + |
| 29 | +--echo # Force using rowid filter made from `key_c` despite being less |
| 30 | +--echo # efficient then the one made from `key_b` |
| 31 | +EXPLAIN EXTENDED |
| 32 | +SELECT /*+ rowid_filter(t1 key_c)*/ a FROM t1 WHERE c < 'e' AND b > 't' and d < 'e'; |
| 33 | + |
| 34 | +--echo # Allow the optimizer to choose the best rowid filter from key_a,key_b,key_c,key_d |
| 35 | +EXPLAIN EXTENDED |
| 36 | +SELECT /*+ rowid_filter(t1 key_a,key_b,key_c,key_d)*/ a FROM t1 |
| 37 | + WHERE c < 'e' AND b > 't' and d < 'e'; |
| 38 | + |
| 39 | +--echo # Forbid `key_b` for rowid filtering, so `key_c` is used |
| 40 | +let $q= SELECT /*+ no_rowid_filter(t1 key_b)*/ a FROM t1 |
| 41 | + WHERE c < 'e' AND b > 't' and d < 'e'; |
| 42 | + |
| 43 | +eval EXPLAIN EXTENDED $q; |
| 44 | +--echo # Validate the result set |
| 45 | +eval $q; |
| 46 | + |
| 47 | +--echo # Forbid both `key_b` and `key_c`, so no rowid filter can be applied |
| 48 | +EXPLAIN EXTENDED |
| 49 | +SELECT /*+ no_rowid_filter(t1 key_b, key_c)*/ a FROM t1 |
| 50 | + WHERE c < 'e' AND b > 't' and d < 'e'; |
| 51 | + |
| 52 | +--echo # Disable rowid filter for indexes which would not be used anyway |
| 53 | +EXPLAIN EXTENDED |
| 54 | +SELECT /*+ no_rowid_filter(t1 key_a)*/ a FROM t1 |
| 55 | + WHERE c < 'e' AND b > 't' and d < 'e'; |
| 56 | + |
| 57 | +EXPLAIN EXTENDED |
| 58 | +SELECT /*+ no_rowid_filter(t1 key_a,key_b)*/ a FROM t1 |
| 59 | + WHERE c < 'e' AND b > 't' and d < 'e'; |
| 60 | + |
| 61 | +--echo # Test the hint with query blocks |
| 62 | +set optimizer_switch='derived_merge=off'; |
| 63 | + |
| 64 | +EXPLAIN EXTENDED |
| 65 | +SELECT /*+ no_rowid_filter(t1@qb1)*/ * FROM ( |
| 66 | + SELECT /*+ qb_name(qb1)*/ a FROM t1 WHERE c < 'e' AND b > 't') dt; |
| 67 | + |
| 68 | +--echo # `key_b|key_c` access is forced |
| 69 | +EXPLAIN EXTENDED |
| 70 | +SELECT /*+ /*+ rowid_filter(t1@qb1 key_c)*/ * FROM ( |
| 71 | + SELECT /*+ qb_name(qb1)*/ a FROM t1 WHERE c < 'e' AND b > 't') dt; |
| 72 | + |
| 73 | +set optimizer_switch=default; |
| 74 | + |
| 75 | +--echo # Turn rowid filtering off and enable it selectively |
| 76 | +set optimizer_switch='rowid_filter=off'; |
| 77 | + |
| 78 | +--echo # Make sure rowid filter is not used when there are no hints: |
| 79 | +EXPLAIN EXTENDED |
| 80 | +SELECT a FROM t1 WHERE c < 'e' AND b > 't' and d < 'e'; |
| 81 | + |
| 82 | +--echo # Enable rowid filter for t1 |
| 83 | +EXPLAIN EXTENDED |
| 84 | +SELECT /*+ rowid_filter(t1)*/ a FROM t1 WHERE c < 'e' AND b > 't' and d < 'e'; |
| 85 | + |
| 86 | +--echo # Enable rowid filter only for some indexes of t1 |
| 87 | +EXPLAIN EXTENDED |
| 88 | +SELECT /*+ rowid_filter(t1 key_a, key_c)*/ a FROM t1 |
| 89 | + WHERE c < 'e' AND b > 't' and d < 'e'; |
| 90 | + |
| 91 | +EXPLAIN EXTENDED |
| 92 | +SELECT /*+ rowid_filter(t1 key_c)*/ a FROM t1 |
| 93 | + WHERE c < 'e' AND b > 't' and d < 'e'; |
| 94 | + |
| 95 | +--echo # Enable rowid filter for the same index that is used to access data (impossible) |
| 96 | +EXPLAIN EXTENDED |
| 97 | +SELECT /*+ rowid_filter(t1 key_d)*/ a FROM t1 WHERE c < 'e' AND b > 't' and d < 'e'; |
| 98 | + |
| 99 | +--echo # Conflicting hints |
| 100 | +EXPLAIN EXTENDED |
| 101 | +SELECT /*+ no_rowid_filter(t1) ROWID_FILTER(t1 key_a)*/a FROM t1 |
| 102 | + WHERE c < 'e' AND b > 't'; |
| 103 | + |
| 104 | +EXPLAIN EXTENDED |
| 105 | +SELECT /*+ no_rowid_filter(t1 key_a, key_b) no_rowid_filter(t1 key_c, key_b)*/a FROM t1 |
| 106 | + WHERE c < 'e' AND b > 't' and d < 'e'; |
| 107 | + |
| 108 | +EXPLAIN EXTENDED |
| 109 | +SELECT /*+ no_rowid_filter(t1 key_a,key_b) rowid_filter(t1 key_c)*/a FROM t1 |
| 110 | + WHERE c < 'e' AND b > 't' and d < 'e'; |
| 111 | + |
| 112 | +# Warnings "Unresolved table/index name..." are generated during both prepare |
| 113 | +# and execution stages. So disable PS protocol to avoid duplication |
| 114 | +--disable_ps_protocol |
| 115 | +--echo # Wrong table name |
| 116 | +EXPLAIN EXTENDED |
| 117 | +SELECT /*+ no_rowid_filter(missing_table)*/a FROM t1 |
| 118 | + WHERE c < 'e' AND b > 't' and d < 'e'; |
| 119 | + |
| 120 | +--echo # Some index names are wrong but key_c is applicable |
| 121 | +EXPLAIN EXTENDED |
| 122 | +SELECT /*+ rowid_filter(t1 wrong_key1, key_c, wrong_key2)*/ a FROM t1 |
| 123 | + WHERE c < 'e' AND b > 't' and d < 'e'; |
| 124 | +--enable_ps_protocol |
| 125 | + |
| 126 | +--echo # Test cases mixing with index hints. |
| 127 | +--echo # Keys must be whitelisted in INDEX()/JOIN_INDEX() hint to be |
| 128 | +--echo # applicable as a rowid filter. ROWID_FILTER() hint cannot enable keys |
| 129 | +--echo # not enabled by INDEX()/JOIN_INDEX() hints or disabled by |
| 130 | +--echo # NO_INDEX()/NO_JOIN_INDEX() hints |
| 131 | +EXPLAIN EXTENDED |
| 132 | +SELECT /*+ index(t1 key_b,key_c) rowid_filter(t1 key_c)*/ a FROM t1 |
| 133 | + WHERE c < 'e' AND b > 't' and d < 'e'; |
| 134 | + |
| 135 | +EXPLAIN EXTENDED |
| 136 | +SELECT /*+ join_index(t1 key_b,key_c) rowid_filter(t1 key_c)*/ a FROM t1 |
| 137 | + WHERE c < 'e' AND b > 't' and d < 'e'; |
| 138 | + |
| 139 | +EXPLAIN EXTENDED |
| 140 | +SELECT /*+ index(t1 key_d,key_c) rowid_filter(t1 key_c)*/ a FROM t1 |
| 141 | + WHERE c < 'e' AND b > 't' and d < 'e'; |
| 142 | + |
| 143 | +EXPLAIN EXTENDED |
| 144 | +SELECT /*+ no_index(t1) rowid_filter(t1 key_c)*/ a FROM t1 |
| 145 | + WHERE c < 'e' AND b > 't' and d < 'e'; |
| 146 | + |
| 147 | +EXPLAIN EXTENDED |
| 148 | +SELECT /*+ no_index(t1 key_d) rowid_filter(t1 key_c)*/ a FROM t1 |
| 149 | + WHERE c < 'e' AND b > 't' and d < 'e'; |
| 150 | + |
| 151 | +EXPLAIN EXTENDED |
| 152 | +SELECT /*+ no_index(t1 key_c) rowid_filter(t1 key_c)*/ a FROM t1 |
| 153 | + WHERE c < 'e' AND b > 't' and d < 'e'; |
| 154 | + |
| 155 | +EXPLAIN EXTENDED |
| 156 | +SELECT /*+ index(t1) no_rowid_filter(t1 key_c)*/ a FROM t1 |
| 157 | + WHERE c < 'e' AND b > 't' and d < 'e'; |
| 158 | + |
| 159 | +--echo # Test cases for old-style hints |
| 160 | +EXPLAIN EXTENDED |
| 161 | +SELECT a FROM t1 FORCE INDEX(key_d, key_b) |
| 162 | + WHERE c < 'e' AND b > 't' and d < 'e'; |
| 163 | + |
| 164 | +--echo # `key_c` is not listed in the hint so is not applicable as rowid filter |
| 165 | +--echo # (also see comment for new-style index hints above) |
| 166 | +EXPLAIN EXTENDED |
| 167 | +SELECT a FROM t1 FORCE INDEX(key_d) |
| 168 | + WHERE c < 'e' AND b > 't' and d < 'e'; |
| 169 | + |
| 170 | +--echo # `key_c` is blacklisted, so `key_b` is used for rowid filter |
| 171 | +EXPLAIN EXTENDED |
| 172 | +SELECT a FROM t1 IGNORE INDEX(key_c) |
| 173 | + WHERE c < 'e' AND b > 't' and d < 'e'; |
| 174 | + |
| 175 | +--echo # `key_b` is blacklisted, so `key_c` is used for rowid filter |
| 176 | +EXPLAIN EXTENDED |
| 177 | +SELECT a FROM t1 IGNORE INDEX(key_b) |
| 178 | + WHERE c < 'e' AND b > 't' and d < 'e'; |
| 179 | + |
| 180 | +DROP TABLE t1; |
0 commit comments