OLD | NEW |
1 # 2013 August 3 | 1 # 2013 August 3 |
2 # | 2 # |
3 # The author disclaims copyright to this source code. In place of | 3 # The author disclaims copyright to this source code. In place of |
4 # a legal notice, here is a blessing: | 4 # a legal notice, here is a blessing: |
5 # | 5 # |
6 # May you do good and not evil. | 6 # May you do good and not evil. |
7 # May you find forgiveness for yourself and forgive others. | 7 # May you find forgiveness for yourself and forgive others. |
8 # May you share freely, never taking more than you give. | 8 # May you share freely, never taking more than you give. |
9 # | 9 # |
10 #*********************************************************************** | 10 #*********************************************************************** |
(...skipping 1116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1127 } { | 1127 } { |
1128 0 0 0 {SEARCH TABLE t6 USING INDEX aa (a<?)} | 1128 0 0 0 {SEARCH TABLE t6 USING INDEX aa (a<?)} |
1129 } | 1129 } |
1130 do_eqp_test 25.4.2 { | 1130 do_eqp_test 25.4.2 { |
1131 SELECT * FROM t6 WHERE a < 20 AND (b BETWEEN ? AND 60) | 1131 SELECT * FROM t6 WHERE a < 20 AND (b BETWEEN ? AND 60) |
1132 } { | 1132 } { |
1133 0 0 0 {SEARCH TABLE t6 USING INDEX bb (b>? AND b<?)} | 1133 0 0 0 {SEARCH TABLE t6 USING INDEX bb (b>? AND b<?)} |
1134 } | 1134 } |
1135 } | 1135 } |
1136 | 1136 |
| 1137 #------------------------------------------------------------------------- |
| 1138 # Check that a problem in they way stat4 data is used has been |
| 1139 # resolved (see below). |
| 1140 # |
| 1141 reset_db |
| 1142 do_test 26.1.1 { |
| 1143 db transaction { |
| 1144 execsql { |
| 1145 CREATE TABLE t1(x, y, z); |
| 1146 CREATE INDEX t1xy ON t1(x, y); |
| 1147 CREATE INDEX t1z ON t1(z); |
| 1148 } |
| 1149 for {set i 0} {$i < 10000} {incr i} { |
| 1150 execsql { INSERT INTO t1(x, y) VALUES($i, $i) } |
| 1151 } |
| 1152 for {set i 0} {$i < 10} {incr i} { |
| 1153 execsql { |
| 1154 WITH cnt(x) AS (SELECT 1 UNION ALL SELECT x+1 FROM cnt WHERE x<100) |
| 1155 INSERT INTO t1(x, y) SELECT 10000+$i, x FROM cnt; |
| 1156 INSERT INTO t1(x, y) SELECT 10000+$i, 100; |
| 1157 } |
| 1158 } |
| 1159 execsql { |
| 1160 UPDATE t1 SET z = rowid / 20; |
| 1161 ANALYZE; |
| 1162 } |
| 1163 } |
| 1164 } {} |
| 1165 |
| 1166 do_execsql_test 26.1.2 { |
| 1167 SELECT count(*) FROM t1 WHERE x = 10000 AND y < 50; |
| 1168 } {49} |
| 1169 do_execsql_test 26.1.3 { |
| 1170 SELECT count(*) FROM t1 WHERE z = 444; |
| 1171 } {20} |
| 1172 |
| 1173 # The analyzer knows that any (z=?) expression matches 20 rows. So it |
| 1174 # will use index "t1z" if the estimate of hits for (x=10000 AND y<50) |
| 1175 # is greater than 20 rows. |
| 1176 # |
| 1177 # And it should be. The analyzer has a stat4 sample as follows: |
| 1178 # |
| 1179 # sample=(x=10000, y=100) nLt=(10000 10099) |
| 1180 # |
| 1181 # There should be no other samples that start with (x=10000). So it knows |
| 1182 # that (x=10000 AND y<50) must match somewhere between 0 and 99 rows, but |
| 1183 # know more than that. Guessing less than 20 is therefore unreasonable. |
| 1184 # |
| 1185 # At one point though, due to a problem in whereKeyStats(), the planner was |
| 1186 # estimating that (x=10000 AND y<50) would match only 2 rows. |
| 1187 # |
| 1188 do_eqp_test 26.1.4 { |
| 1189 SELECT * FROM t1 WHERE x = 10000 AND y < 50 AND z = 444; |
| 1190 } { |
| 1191 0 0 0 {SEARCH TABLE t1 USING INDEX t1z (z=?)} |
| 1192 } |
| 1193 |
| 1194 |
| 1195 # This test - 26.2.* - tests that another manifestation of the same problem |
| 1196 # is no longer present in the library. Assuming: |
| 1197 # |
| 1198 # CREATE INDEX t1xy ON t1(x, y) |
| 1199 # |
| 1200 # and that have samples for index t1xy as follows: |
| 1201 # |
| 1202 # |
| 1203 # sample=('A', 70) nEq=(100, 2) nLt=(900, 970) |
| 1204 # sample=('B', 70) nEq=(100, 2) nLt=(1000, 1070) |
| 1205 # |
| 1206 # the planner should estimate that (x = 'B' AND y > 25) matches 76 rows |
| 1207 # (70 * 2/3 + 30). Before, due to the problem, the planner was estimating |
| 1208 # that this matched 100 rows. |
| 1209 # |
| 1210 reset_db |
| 1211 do_execsql_test 26.2.1 { |
| 1212 BEGIN; |
| 1213 CREATE TABLE t1(x, y, z); |
| 1214 CREATE INDEX i1 ON t1(x, y); |
| 1215 CREATE INDEX i2 ON t1(z); |
| 1216 |
| 1217 WITH |
| 1218 cnt(y) AS (SELECT 0 UNION ALL SELECT y+1 FROM cnt WHERE y<99), |
| 1219 letters(x) AS ( |
| 1220 SELECT 'A' UNION SELECT 'B' UNION SELECT 'C' UNION SELECT 'D' |
| 1221 ) |
| 1222 INSERT INTO t1(x, y) SELECT x, y FROM letters, cnt; |
| 1223 |
| 1224 WITH |
| 1225 letters(x) AS ( |
| 1226 SELECT 'A' UNION SELECT 'B' UNION SELECT 'C' UNION SELECT 'D' |
| 1227 ) |
| 1228 INSERT INTO t1(x, y) SELECT x, 70 FROM letters; |
| 1229 |
| 1230 WITH |
| 1231 cnt(i) AS (SELECT 0 UNION ALL SELECT i+1 FROM cnt WHERE i<9999) |
| 1232 INSERT INTO t1(x, y) SELECT i, i FROM cnt; |
| 1233 |
| 1234 UPDATE t1 SET z = (rowid / 95); |
| 1235 ANALYZE; |
| 1236 COMMIT; |
| 1237 } |
| 1238 |
| 1239 do_eqp_test 26.2.2 { |
| 1240 SELECT * FROM t1 WHERE x='B' AND y>25 AND z=?; |
| 1241 } { |
| 1242 0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x=? AND y>?)} |
| 1243 } |
| 1244 |
| 1245 |
1137 finish_test | 1246 finish_test |
| 1247 |
| 1248 |
| 1249 |
OLD | NEW |