Annotation of embedaddon/sqlite3/test/autoindex1.test, revision 1.1
1.1 ! misho 1: # 2010 April 07
! 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: # This file implements regression tests for SQLite library. The
! 12: # focus of this script is testing automatic index creation logic.
! 13: #
! 14:
! 15: set testdir [file dirname $argv0]
! 16: source $testdir/tester.tcl
! 17:
! 18: # If the library is not compiled with automatic index support then
! 19: # skip all tests in this file.
! 20: #
! 21: ifcapable {!autoindex} {
! 22: finish_test
! 23: return
! 24: }
! 25:
! 26: # With automatic index turned off, we do a full scan of the T2 table
! 27: do_test autoindex1-100 {
! 28: db eval {
! 29: CREATE TABLE t1(a,b);
! 30: INSERT INTO t1 VALUES(1,11);
! 31: INSERT INTO t1 VALUES(2,22);
! 32: INSERT INTO t1 SELECT a+2, b+22 FROM t1;
! 33: INSERT INTO t1 SELECT a+4, b+44 FROM t1;
! 34: CREATE TABLE t2(c,d);
! 35: INSERT INTO t2 SELECT a, 900+b FROM t1;
! 36: }
! 37: db eval {
! 38: PRAGMA automatic_index=OFF;
! 39: SELECT b, d FROM t1 JOIN t2 ON a=c ORDER BY b;
! 40: }
! 41: } {11 911 22 922 33 933 44 944 55 955 66 966 77 977 88 988}
! 42: do_test autoindex1-101 {
! 43: db status step
! 44: } {63}
! 45: do_test autoindex1-102 {
! 46: db status autoindex
! 47: } {0}
! 48:
! 49: # With autoindex turned on, we build an index once and then use that index
! 50: # to find T2 values.
! 51: do_test autoindex1-110 {
! 52: db eval {
! 53: PRAGMA automatic_index=ON;
! 54: SELECT b, d FROM t1 JOIN t2 ON a=c ORDER BY b;
! 55: }
! 56: } {11 911 22 922 33 933 44 944 55 955 66 966 77 977 88 988}
! 57: do_test autoindex1-111 {
! 58: db status step
! 59: } {7}
! 60: do_test autoindex1-112 {
! 61: db status autoindex
! 62: } {7}
! 63:
! 64: # The same test as above, but this time the T2 query is a subquery rather
! 65: # than a join.
! 66: do_test autoindex1-200 {
! 67: db eval {
! 68: PRAGMA automatic_index=OFF;
! 69: SELECT b, (SELECT d FROM t2 WHERE c=a) FROM t1;
! 70: }
! 71: } {11 911 22 922 33 933 44 944 55 955 66 966 77 977 88 988}
! 72: do_test autoindex1-201 {
! 73: db status step
! 74: } {35}
! 75: do_test autoindex1-202 {
! 76: db status autoindex
! 77: } {0}
! 78: do_test autoindex1-210 {
! 79: db eval {
! 80: PRAGMA automatic_index=ON;
! 81: SELECT b, (SELECT d FROM t2 WHERE c=a) FROM t1;
! 82: }
! 83: } {11 911 22 922 33 933 44 944 55 955 66 966 77 977 88 988}
! 84: do_test autoindex1-211 {
! 85: db status step
! 86: } {7}
! 87: do_test autoindex1-212 {
! 88: db status autoindex
! 89: } {7}
! 90:
! 91:
! 92: # Modify the second table of the join while the join is in progress
! 93: #
! 94: do_test autoindex1-300 {
! 95: set r {}
! 96: db eval {SELECT b, d FROM t1 JOIN t2 ON (c=a)} {
! 97: lappend r $b $d
! 98: db eval {UPDATE t2 SET d=d+1}
! 99: }
! 100: set r
! 101: } {11 911 22 922 33 933 44 944 55 955 66 966 77 977 88 988}
! 102: do_test autoindex1-310 {
! 103: db eval {SELECT d FROM t2 ORDER BY d}
! 104: } {919 930 941 952 963 974 985 996}
! 105:
! 106: # The next test does a 10-way join on unindexed tables. Without
! 107: # automatic indices, the join will take a long time to complete.
! 108: # With automatic indices, it should only take about a second.
! 109: #
! 110: do_test autoindex1-400 {
! 111: db eval {
! 112: CREATE TABLE t4(a, b);
! 113: INSERT INTO t4 VALUES(1,2);
! 114: INSERT INTO t4 VALUES(2,3);
! 115: }
! 116: for {set n 2} {$n<4096} {set n [expr {$n+$n}]} {
! 117: db eval {INSERT INTO t4 SELECT a+$n, b+$n FROM t4}
! 118: }
! 119: db eval {
! 120: SELECT count(*) FROM t4;
! 121: }
! 122: } {4096}
! 123: do_test autoindex1-401 {
! 124: db eval {
! 125: SELECT count(*)
! 126: FROM t4 AS x1
! 127: JOIN t4 AS x2 ON x2.a=x1.b
! 128: JOIN t4 AS x3 ON x3.a=x2.b
! 129: JOIN t4 AS x4 ON x4.a=x3.b
! 130: JOIN t4 AS x5 ON x5.a=x4.b
! 131: JOIN t4 AS x6 ON x6.a=x5.b
! 132: JOIN t4 AS x7 ON x7.a=x6.b
! 133: JOIN t4 AS x8 ON x8.a=x7.b
! 134: JOIN t4 AS x9 ON x9.a=x8.b
! 135: JOIN t4 AS x10 ON x10.a=x9.b;
! 136: }
! 137: } {4087}
! 138:
! 139: # Ticket [8011086c85c6c404014c947fcf3eb9f42b184a0d] from 2010-07-08
! 140: # Make sure automatic indices are not created for the RHS of an IN expression
! 141: # that is not a correlated subquery.
! 142: #
! 143: do_execsql_test autoindex1-500 {
! 144: CREATE TABLE t501(a INTEGER PRIMARY KEY, b);
! 145: CREATE TABLE t502(x INTEGER PRIMARY KEY, y);
! 146: EXPLAIN QUERY PLAN
! 147: SELECT b FROM t501
! 148: WHERE t501.a IN (SELECT x FROM t502 WHERE y=?);
! 149: } {
! 150: 0 0 0 {SEARCH TABLE t501 USING INTEGER PRIMARY KEY (rowid=?) (~25 rows)}
! 151: 0 0 0 {EXECUTE LIST SUBQUERY 1}
! 152: 1 0 0 {SCAN TABLE t502 (~100000 rows)}
! 153: }
! 154: do_execsql_test autoindex1-501 {
! 155: EXPLAIN QUERY PLAN
! 156: SELECT b FROM t501
! 157: WHERE t501.a IN (SELECT x FROM t502 WHERE y=t501.b);
! 158: } {
! 159: 0 0 0 {SCAN TABLE t501 (~500000 rows)}
! 160: 0 0 0 {EXECUTE CORRELATED LIST SUBQUERY 1}
! 161: 1 0 0 {SEARCH TABLE t502 USING AUTOMATIC COVERING INDEX (y=?) (~7 rows)}
! 162: }
! 163: do_execsql_test autoindex1-502 {
! 164: EXPLAIN QUERY PLAN
! 165: SELECT b FROM t501
! 166: WHERE t501.a=123
! 167: AND t501.a IN (SELECT x FROM t502 WHERE y=t501.b);
! 168: } {
! 169: 0 0 0 {SEARCH TABLE t501 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}
! 170: 0 0 0 {EXECUTE CORRELATED LIST SUBQUERY 1}
! 171: 1 0 0 {SCAN TABLE t502 (~100000 rows)}
! 172: }
! 173:
! 174:
! 175: # The following code checks a performance regression reported on the
! 176: # mailing list on 2010-10-19. The problem is that the nRowEst field
! 177: # of ephermeral tables was not being initialized correctly and so no
! 178: # automatic index was being created for the emphemeral table when it was
! 179: # used as part of a join.
! 180: #
! 181: do_execsql_test autoindex1-600 {
! 182: CREATE TABLE flock_owner(
! 183: owner_rec_id INTEGER CONSTRAINT flock_owner_key PRIMARY KEY,
! 184: flock_no VARCHAR(6) NOT NULL REFERENCES flock (flock_no),
! 185: owner_person_id INTEGER NOT NULL REFERENCES person (person_id),
! 186: owner_change_date TEXT, last_changed TEXT NOT NULL,
! 187: CONSTRAINT fo_owner_date UNIQUE (flock_no, owner_change_date)
! 188: );
! 189: CREATE TABLE sheep (
! 190: Sheep_No char(7) NOT NULL,
! 191: Date_of_Birth char(8),
! 192: Sort_DoB text,
! 193: Flock_Book_Vol char(2),
! 194: Breeder_No char(6),
! 195: Breeder_Person integer,
! 196: Originating_Flock char(6),
! 197: Registering_Flock char(6),
! 198: Tag_Prefix char(9),
! 199: Tag_No char(15),
! 200: Sort_Tag_No integer,
! 201: Breeders_Temp_Tag char(15),
! 202: Sex char(1),
! 203: Sheep_Name char(32),
! 204: Sire_No char(7),
! 205: Dam_No char(7),
! 206: Register_Code char(1),
! 207: Colour char(48),
! 208: Colour_Code char(2),
! 209: Pattern_Code char(8),
! 210: Horns char(1),
! 211: Litter_Size char(1),
! 212: Coeff_of_Inbreeding real,
! 213: Date_of_Registration text,
! 214: Date_Last_Changed text,
! 215: UNIQUE(Sheep_No));
! 216: CREATE INDEX fo_flock_no_index
! 217: ON flock_owner (flock_no);
! 218: CREATE INDEX fo_owner_change_date_index
! 219: ON flock_owner (owner_change_date);
! 220: CREATE INDEX fo_owner_person_id_index
! 221: ON flock_owner (owner_person_id);
! 222: CREATE INDEX sheep_org_flock_index
! 223: ON sheep (originating_flock);
! 224: CREATE INDEX sheep_reg_flock_index
! 225: ON sheep (registering_flock);
! 226: EXPLAIN QUERY PLAN
! 227: SELECT x.sheep_no, x.registering_flock, x.date_of_registration
! 228: FROM sheep x LEFT JOIN
! 229: (SELECT s.sheep_no, prev.flock_no, prev.owner_person_id,
! 230: s.date_of_registration, prev.owner_change_date
! 231: FROM sheep s JOIN flock_owner prev ON s.registering_flock =
! 232: prev.flock_no
! 233: AND (prev.owner_change_date <= s.date_of_registration || ' 00:00:00')
! 234: WHERE NOT EXISTS
! 235: (SELECT 'x' FROM flock_owner later
! 236: WHERE prev.flock_no = later.flock_no
! 237: AND later.owner_change_date > prev.owner_change_date
! 238: AND later.owner_change_date <= s.date_of_registration||' 00:00:00')
! 239: ) y ON x.sheep_no = y.sheep_no
! 240: WHERE y.sheep_no IS NULL
! 241: ORDER BY x.registering_flock;
! 242: } {
! 243: 1 0 0 {SCAN TABLE sheep AS s (~1000000 rows)}
! 244: 1 1 1 {SEARCH TABLE flock_owner AS prev USING INDEX sqlite_autoindex_flock_owner_1 (flock_no=? AND owner_change_date<?) (~2 rows)}
! 245: 1 0 0 {EXECUTE CORRELATED SCALAR SUBQUERY 2}
! 246: 2 0 0 {SEARCH TABLE flock_owner AS later USING COVERING INDEX sqlite_autoindex_flock_owner_1 (flock_no=? AND owner_change_date>? AND owner_change_date<?) (~1 rows)}
! 247: 0 0 0 {SCAN TABLE sheep AS x USING INDEX sheep_reg_flock_index (~1000000 rows)}
! 248: 0 1 1 {SEARCH SUBQUERY 1 AS y USING AUTOMATIC COVERING INDEX (sheep_no=?) (~8 rows)}
! 249: }
! 250:
! 251:
! 252: do_execsql_test autoindex1-700 {
! 253: CREATE TABLE t5(a, b, c);
! 254: EXPLAIN QUERY PLAN SELECT a FROM t5 WHERE b=10 ORDER BY c;
! 255: } {
! 256: 0 0 0 {SCAN TABLE t5 (~100000 rows)}
! 257: 0 0 0 {USE TEMP B-TREE FOR ORDER BY}
! 258: }
! 259:
! 260:
! 261: finish_test
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>