OLD | NEW |
(Empty) | |
| 1 # 2014-04-26 |
| 2 # |
| 3 # The author disclaims copyright to this source code. In place of |
| 4 # a legal notice, here is a blessing: |
| 5 # |
| 6 # May you do good and not evil. |
| 7 # May you find forgiveness for yourself and forgive others. |
| 8 # May you share freely, never taking more than you give. |
| 9 # |
| 10 #*********************************************************************** |
| 11 # |
| 12 |
| 13 set testdir [file dirname $argv0] |
| 14 source $testdir/tester.tcl |
| 15 set testprefix cost |
| 16 |
| 17 |
| 18 do_execsql_test 1.1 { |
| 19 CREATE TABLE t3(id INTEGER PRIMARY KEY, b NOT NULL); |
| 20 CREATE TABLE t4(c, d, e); |
| 21 CREATE UNIQUE INDEX i3 ON t3(b); |
| 22 CREATE UNIQUE INDEX i4 ON t4(c, d); |
| 23 } |
| 24 do_eqp_test 1.2 { |
| 25 SELECT e FROM t3, t4 WHERE b=c ORDER BY b, d; |
| 26 } { |
| 27 0 0 0 {SCAN TABLE t3 USING COVERING INDEX i3} |
| 28 0 1 1 {SEARCH TABLE t4 USING INDEX i4 (c=?)} |
| 29 } |
| 30 |
| 31 |
| 32 do_execsql_test 2.1 { |
| 33 CREATE TABLE t1(a, b); |
| 34 CREATE INDEX i1 ON t1(a); |
| 35 } |
| 36 |
| 37 # It is better to use an index for ORDER BY than sort externally, even |
| 38 # if the index is a non-covering index. |
| 39 do_eqp_test 2.2 { |
| 40 SELECT * FROM t1 ORDER BY a; |
| 41 } { |
| 42 0 0 0 {SCAN TABLE t1 USING INDEX i1} |
| 43 } |
| 44 |
| 45 do_execsql_test 3.1 { |
| 46 CREATE TABLE t5(a INTEGER PRIMARY KEY,b,c,d,e,f,g); |
| 47 CREATE INDEX t5b ON t5(b); |
| 48 CREATE INDEX t5c ON t5(c); |
| 49 CREATE INDEX t5d ON t5(d); |
| 50 CREATE INDEX t5e ON t5(e); |
| 51 CREATE INDEX t5f ON t5(f); |
| 52 CREATE INDEX t5g ON t5(g); |
| 53 } |
| 54 |
| 55 do_eqp_test 3.2 { |
| 56 SELECT a FROM t5 |
| 57 WHERE b IS NULL OR c IS NULL OR d IS NULL |
| 58 ORDER BY a; |
| 59 } { |
| 60 0 0 0 {SEARCH TABLE t5 USING INDEX t5b (b=?)} |
| 61 0 0 0 {SEARCH TABLE t5 USING INDEX t5c (c=?)} |
| 62 0 0 0 {SEARCH TABLE t5 USING INDEX t5d (d=?)} |
| 63 0 0 0 {USE TEMP B-TREE FOR ORDER BY} |
| 64 } |
| 65 |
| 66 #------------------------------------------------------------------------- |
| 67 # If there is no likelihood() or stat3 data, SQLite assumes that a closed |
| 68 # range scan (e.g. one constrained by "col BETWEEN ? AND ?" constraint) |
| 69 # visits 1/64 of the rows in a table. |
| 70 # |
| 71 # Note: 1/63 =~ 0.016 |
| 72 # Note: 1/65 =~ 0.015 |
| 73 # |
| 74 reset_db |
| 75 do_execsql_test 4.1 { |
| 76 CREATE TABLE t1(a, b); |
| 77 CREATE INDEX i1 ON t1(a); |
| 78 CREATE INDEX i2 ON t1(b); |
| 79 } |
| 80 do_eqp_test 4.2 { |
| 81 SELECT * FROM t1 WHERE likelihood(a=?, 0.014) AND b BETWEEN ? AND ?; |
| 82 } { |
| 83 0 0 0 {SEARCH TABLE t1 USING INDEX i1 (a=?)} |
| 84 } |
| 85 do_eqp_test 4.3 { |
| 86 SELECT * FROM t1 WHERE likelihood(a=?, 0.016) AND b BETWEEN ? AND ?; |
| 87 } { |
| 88 0 0 0 {SEARCH TABLE t1 USING INDEX i2 (b>? AND b<?)} |
| 89 } |
| 90 |
| 91 |
| 92 #------------------------------------------------------------------------- |
| 93 # |
| 94 reset_db |
| 95 do_execsql_test 5.1 { |
| 96 CREATE TABLE t2(x, y); |
| 97 CREATE INDEX t2i1 ON t2(x); |
| 98 } |
| 99 |
| 100 do_eqp_test 5.2 { |
| 101 SELECT * FROM t2 ORDER BY x, y; |
| 102 } { |
| 103 0 0 0 {SCAN TABLE t2 USING INDEX t2i1} |
| 104 0 0 0 {USE TEMP B-TREE FOR RIGHT PART OF ORDER BY} |
| 105 } |
| 106 |
| 107 do_eqp_test 5.3 { |
| 108 SELECT * FROM t2 WHERE x BETWEEN ? AND ? ORDER BY rowid; |
| 109 } { |
| 110 0 0 0 {SEARCH TABLE t2 USING INDEX t2i1 (x>? AND x<?)} |
| 111 0 0 0 {USE TEMP B-TREE FOR ORDER BY} |
| 112 } |
| 113 |
| 114 # where7.test, where8.test: |
| 115 # |
| 116 do_execsql_test 6.1 { |
| 117 CREATE TABLE t3(a INTEGER PRIMARY KEY, b, c); |
| 118 CREATE INDEX t3i1 ON t3(b); |
| 119 CREATE INDEX t3i2 ON t3(c); |
| 120 } |
| 121 |
| 122 do_eqp_test 6.2 { |
| 123 SELECT a FROM t3 WHERE (b BETWEEN 2 AND 4) OR c=100 ORDER BY a |
| 124 } { |
| 125 0 0 0 {SEARCH TABLE t3 USING INDEX t3i1 (b>? AND b<?)} |
| 126 0 0 0 {SEARCH TABLE t3 USING INDEX t3i2 (c=?)} |
| 127 0 0 0 {USE TEMP B-TREE FOR ORDER BY} |
| 128 } |
| 129 |
| 130 #------------------------------------------------------------------------- |
| 131 # |
| 132 reset_db |
| 133 do_execsql_test 7.1 { |
| 134 CREATE TABLE t1(a INTEGER PRIMARY KEY,b,c,d,e,f,g); |
| 135 CREATE INDEX t1b ON t1(b); |
| 136 CREATE INDEX t1c ON t1(c); |
| 137 CREATE INDEX t1d ON t1(d); |
| 138 CREATE INDEX t1e ON t1(e); |
| 139 CREATE INDEX t1f ON t1(f); |
| 140 CREATE INDEX t1g ON t1(g); |
| 141 } |
| 142 |
| 143 do_eqp_test 7.2 { |
| 144 SELECT a FROM t1 |
| 145 WHERE (b>=950 AND b<=1010) OR (b IS NULL AND c NOT NULL) |
| 146 ORDER BY a |
| 147 } { |
| 148 0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)} |
| 149 0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?)} |
| 150 0 0 0 {USE TEMP B-TREE FOR ORDER BY} |
| 151 } |
| 152 |
| 153 do_eqp_test 7.3 { |
| 154 SELECT rowid FROM t1 |
| 155 WHERE (+b IS NULL AND c NOT NULL AND d NOT NULL) |
| 156 OR (b NOT NULL AND c IS NULL AND d NOT NULL) |
| 157 OR (b NOT NULL AND c NOT NULL AND d IS NULL) |
| 158 } { |
| 159 0 0 0 {SCAN TABLE t1} |
| 160 } |
| 161 |
| 162 do_eqp_test 7.4 { |
| 163 SELECT rowid FROM t1 WHERE (+b IS NULL AND c NOT NULL) OR c IS NULL |
| 164 } { |
| 165 0 0 0 {SCAN TABLE t1} |
| 166 } |
| 167 |
| 168 #------------------------------------------------------------------------- |
| 169 # |
| 170 reset_db |
| 171 do_execsql_test 8.1 { |
| 172 CREATE TABLE composer( |
| 173 cid INTEGER PRIMARY KEY, |
| 174 cname TEXT |
| 175 ); |
| 176 CREATE TABLE album( |
| 177 aid INTEGER PRIMARY KEY, |
| 178 aname TEXT |
| 179 ); |
| 180 CREATE TABLE track( |
| 181 tid INTEGER PRIMARY KEY, |
| 182 cid INTEGER REFERENCES composer, |
| 183 aid INTEGER REFERENCES album, |
| 184 title TEXT |
| 185 ); |
| 186 CREATE INDEX track_i1 ON track(cid); |
| 187 CREATE INDEX track_i2 ON track(aid); |
| 188 } |
| 189 |
| 190 do_eqp_test 8.2 { |
| 191 SELECT DISTINCT aname |
| 192 FROM album, composer, track |
| 193 WHERE cname LIKE '%bach%' |
| 194 AND unlikely(composer.cid=track.cid) |
| 195 AND unlikely(album.aid=track.aid); |
| 196 } { |
| 197 0 0 2 {SCAN TABLE track} |
| 198 0 1 0 {SEARCH TABLE album USING INTEGER PRIMARY KEY (rowid=?)} |
| 199 0 2 1 {SEARCH TABLE composer USING INTEGER PRIMARY KEY (rowid=?)} |
| 200 0 0 0 {USE TEMP B-TREE FOR DISTINCT} |
| 201 } |
| 202 |
| 203 #------------------------------------------------------------------------- |
| 204 # |
| 205 do_execsql_test 9.1 { |
| 206 CREATE TABLE t1( |
| 207 a,b,c,d,e, f,g,h,i,j, |
| 208 k,l,m,n,o, p,q,r,s,t |
| 209 ); |
| 210 CREATE INDEX i1 ON t1(k,l,m,n,o,p,q,r,s,t); |
| 211 } |
| 212 do_test 9.2 { |
| 213 for {set i 0} {$i < 100} {incr i} { |
| 214 execsql { INSERT INTO t1 DEFAULT VALUES } |
| 215 } |
| 216 execsql { |
| 217 ANALYZE; |
| 218 CREATE INDEX i2 ON t1(a,b,c,d,e,f,g,h,i,j); |
| 219 } |
| 220 } {} |
| 221 |
| 222 set L [list a=? b=? c=? d=? e=? f=? g=? h=? i=? j=?] |
| 223 foreach {tn nTerm nRow} { |
| 224 1 1 10 |
| 225 2 2 9 |
| 226 3 3 8 |
| 227 4 4 7 |
| 228 5 5 6 |
| 229 6 6 5 |
| 230 7 7 5 |
| 231 8 8 5 |
| 232 9 9 5 |
| 233 10 10 5 |
| 234 } { |
| 235 set w [join [lrange $L 0 [expr $nTerm-1]] " AND "] |
| 236 set p1 [expr ($nRow-1) / 100.0] |
| 237 set p2 [expr ($nRow+1) / 100.0] |
| 238 |
| 239 set sql1 "SELECT * FROM t1 WHERE likelihood(k=?, $p1) AND $w" |
| 240 set sql2 "SELECT * FROM t1 WHERE likelihood(k=?, $p2) AND $w" |
| 241 |
| 242 do_eqp_test 9.3.$tn.1 $sql1 {/INDEX i1/} |
| 243 do_eqp_test 9.3.$tn.2 $sql2 {/INDEX i2/} |
| 244 } |
| 245 |
| 246 |
| 247 #------------------------------------------------------------------------- |
| 248 # |
| 249 |
| 250 ifcapable stat4 { |
| 251 do_execsql_test 10.1 { |
| 252 CREATE TABLE t6(a, b, c); |
| 253 CREATE INDEX t6i1 ON t6(a, b); |
| 254 CREATE INDEX t6i2 ON t6(c); |
| 255 } |
| 256 |
| 257 do_test 10.2 { |
| 258 for {set i 0} {$i < 16} {incr i} { |
| 259 execsql { INSERT INTO t6 VALUES($i%4, 'xyz', $i%8) } |
| 260 } |
| 261 execsql ANALYZE |
| 262 } {} |
| 263 |
| 264 do_eqp_test 10.3 { |
| 265 SELECT rowid FROM t6 WHERE a=0 AND c=0 |
| 266 } { |
| 267 0 0 0 {SEARCH TABLE t6 USING INDEX t6i2 (c=?)} |
| 268 } |
| 269 |
| 270 do_eqp_test 10.4 { |
| 271 SELECT rowid FROM t6 WHERE a=0 AND b='xyz' AND c=0 |
| 272 } { |
| 273 0 0 0 {SEARCH TABLE t6 USING INDEX t6i2 (c=?)} |
| 274 } |
| 275 |
| 276 do_eqp_test 10.5 { |
| 277 SELECT rowid FROM t6 WHERE likelihood(a=0, 0.1) AND c=0 |
| 278 } { |
| 279 0 0 0 {SEARCH TABLE t6 USING INDEX t6i1 (a=?)} |
| 280 } |
| 281 |
| 282 do_eqp_test 10.6 { |
| 283 SELECT rowid FROM t6 WHERE likelihood(a=0, 0.1) AND b='xyz' AND c=0 |
| 284 } { |
| 285 0 0 0 {SEARCH TABLE t6 USING INDEX t6i1 (a=? AND b=?)} |
| 286 } |
| 287 } |
| 288 |
| 289 finish_test |
| 290 |
| 291 |
| 292 |
OLD | NEW |