xref: /sqlite-3.40.0/test/speed2.test (revision 86a88114)
1e4dd73b4Sdrh# 2006 November 23
2e4dd73b4Sdrh#
3e4dd73b4Sdrh# The author disclaims copyright to this source code.  In place of
4e4dd73b4Sdrh# a legal notice, here is a blessing:
5e4dd73b4Sdrh#
6e4dd73b4Sdrh#    May you do good and not evil.
7e4dd73b4Sdrh#    May you find forgiveness for yourself and forgive others.
8e4dd73b4Sdrh#    May you share freely, never taking more than you give.
9e4dd73b4Sdrh#
10e4dd73b4Sdrh#*************************************************************************
11e4dd73b4Sdrh# This file implements regression tests for SQLite library.  The
12e4dd73b4Sdrh# focus of this script is measuring executing speed.
13e4dd73b4Sdrh#
14*86a88114Sdrh# $Id: speed2.test,v 1.7 2007/04/16 15:02:20 drh Exp $
15e4dd73b4Sdrh#
16e4dd73b4Sdrh
17e4dd73b4Sdrhset testdir [file dirname $argv0]
18e4dd73b4Sdrhsource $testdir/tester.tcl
19dd92431aSdrhspeed_trial_init speed2
20e4dd73b4Sdrh
2145068f4bSdrh# Set a uniform random seed
2245068f4bSdrhexpr srand(0)
2345068f4bSdrh
2491c58e23Sdrhset sqlout [open speed2.txt w]
25e4dd73b4Sdrhproc tracesql {sql} {
26e4dd73b4Sdrh  puts $::sqlout $sql\;
27e4dd73b4Sdrh}
28e4dd73b4Sdrh#db trace tracesql
29e4dd73b4Sdrh
30e4dd73b4Sdrh# The number_name procedure below converts its argment (an integer)
31e4dd73b4Sdrh# into a string which is the English-language name for that number.
32e4dd73b4Sdrh#
33e4dd73b4Sdrh# Example:
34e4dd73b4Sdrh#
35e4dd73b4Sdrh#     puts [number_name 123]   ->  "one hundred twenty three"
36e4dd73b4Sdrh#
37e4dd73b4Sdrhset ones {zero one two three four five six seven eight nine
38e4dd73b4Sdrh          ten eleven twelve thirteen fourteen fifteen sixteen seventeen
39e4dd73b4Sdrh          eighteen nineteen}
40e4dd73b4Sdrhset tens {{} ten twenty thirty forty fifty sixty seventy eighty ninety}
41e4dd73b4Sdrhproc number_name {n} {
42e4dd73b4Sdrh  if {$n>=1000} {
43e4dd73b4Sdrh    set txt "[number_name [expr {$n/1000}]] thousand"
44e4dd73b4Sdrh    set n [expr {$n%1000}]
45e4dd73b4Sdrh  } else {
46e4dd73b4Sdrh    set txt {}
47e4dd73b4Sdrh  }
48e4dd73b4Sdrh  if {$n>=100} {
49e4dd73b4Sdrh    append txt " [lindex $::ones [expr {$n/100}]] hundred"
50e4dd73b4Sdrh    set n [expr {$n%100}]
51e4dd73b4Sdrh  }
52e4dd73b4Sdrh  if {$n>=20} {
53e4dd73b4Sdrh    append txt " [lindex $::tens [expr {$n/10}]]"
54e4dd73b4Sdrh    set n [expr {$n%10}]
55e4dd73b4Sdrh  }
56e4dd73b4Sdrh  if {$n>0} {
57e4dd73b4Sdrh    append txt " [lindex $::ones $n]"
58e4dd73b4Sdrh  }
59e4dd73b4Sdrh  set txt [string trim $txt]
60e4dd73b4Sdrh  if {$txt==""} {set txt zero}
61e4dd73b4Sdrh  return $txt
62e4dd73b4Sdrh}
63e4dd73b4Sdrh
64e4dd73b4Sdrh# Create a database schema.
65e4dd73b4Sdrh#
6691c58e23Sdrhdo_test speed2-1.0 {
67e4dd73b4Sdrh  execsql {
68e4dd73b4Sdrh    PRAGMA page_size=1024;
69e4dd73b4Sdrh    PRAGMA cache_size=8192;
70*86a88114Sdrh    PRAGMA locking_mode=EXCLUSIVE;
71e4dd73b4Sdrh    CREATE TABLE t1(a INTEGER, b INTEGER, c TEXT);
72e4dd73b4Sdrh    CREATE TABLE t2(a INTEGER, b INTEGER, c TEXT);
73e4dd73b4Sdrh    CREATE INDEX i2a ON t2(a);
74e4dd73b4Sdrh    CREATE INDEX i2b ON t2(b);
75e4dd73b4Sdrh  }
76e4dd73b4Sdrh  execsql {
77e4dd73b4Sdrh    SELECT name FROM sqlite_master ORDER BY 1;
78e4dd73b4Sdrh  }
79e4dd73b4Sdrh} {i2a i2b t1 t2}
80e4dd73b4Sdrh
81e4dd73b4Sdrh
82e4dd73b4Sdrh# 50000 INSERTs on an unindexed table
83e4dd73b4Sdrh#
84e4dd73b4Sdrhset sql {}
85e4dd73b4Sdrhfor {set i 1} {$i<=50000} {incr i} {
86e4dd73b4Sdrh  set r [expr {int(rand()*500000)}]
87e4dd73b4Sdrh  append sql "INSERT INTO t1 VALUES($i,$r,'[number_name $r]');\n"
88e4dd73b4Sdrh}
89e4dd73b4Sdrhdb eval BEGIN
9091c58e23Sdrhspeed_trial speed2-insert1 50000 row $sql
91e4dd73b4Sdrhdb eval COMMIT
92e4dd73b4Sdrh
93e4dd73b4Sdrh# 50000 INSERTs on an indexed table
94e4dd73b4Sdrh#
95e4dd73b4Sdrhset sql {}
96e4dd73b4Sdrhfor {set i 1} {$i<=50000} {incr i} {
97e4dd73b4Sdrh  set r [expr {int(rand()*500000)}]
98e4dd73b4Sdrh  append sql "INSERT INTO t2 VALUES($i,$r,'[number_name $r]');\n"
99e4dd73b4Sdrh}
100e4dd73b4Sdrhdb eval BEGIN
10191c58e23Sdrhspeed_trial speed2-insert2 50000 row $sql
102e4dd73b4Sdrhdb eval COMMIT
103e4dd73b4Sdrh
104e4dd73b4Sdrh
105e4dd73b4Sdrh
106e4dd73b4Sdrh# 50 SELECTs on an integer comparison.  There is no index so
107e4dd73b4Sdrh# a full table scan is required.
108e4dd73b4Sdrh#
109e4dd73b4Sdrhset sql {}
110e4dd73b4Sdrhfor {set i 0} {$i<50} {incr i} {
111e4dd73b4Sdrh  set lwr [expr {$i*100}]
112e4dd73b4Sdrh  set upr [expr {($i+10)*100}]
113e4dd73b4Sdrh  append sql "SELECT count(*), avg(b) FROM t1 WHERE b>=$lwr AND b<$upr;"
114e4dd73b4Sdrh}
11595bad4c7Sdrhspeed_trial speed2-select1a [expr {50*50000}] row $sql
116e4dd73b4Sdrh
117e4dd73b4Sdrh# 50 SELECTs on an LIKE comparison.  There is no index so a full
118e4dd73b4Sdrh# table scan is required.
119e4dd73b4Sdrh#
120e4dd73b4Sdrhset sql {}
121e4dd73b4Sdrhfor {set i 0} {$i<50} {incr i} {
122e4dd73b4Sdrh  append sql \
123e4dd73b4Sdrh    "SELECT count(*), avg(b) FROM t1 WHERE c LIKE '%[number_name $i]%';"
124e4dd73b4Sdrh}
12595bad4c7Sdrhspeed_trial speed2-select2a [expr {50*50000}] row $sql
12695bad4c7Sdrh
12795bad4c7Sdrh# Vacuum
12895bad4c7Sdrhspeed_trial speed2-vacuum1 100000 row VACUUM
12995bad4c7Sdrh
13095bad4c7Sdrh# 50 SELECTs on an integer comparison.  There is no index so
13195bad4c7Sdrh# a full table scan is required.
13295bad4c7Sdrh#
13395bad4c7Sdrhset sql {}
13495bad4c7Sdrhfor {set i 0} {$i<50} {incr i} {
13595bad4c7Sdrh  set lwr [expr {$i*100}]
13695bad4c7Sdrh  set upr [expr {($i+10)*100}]
13795bad4c7Sdrh  append sql "SELECT count(*), avg(b) FROM t1 WHERE b>=$lwr AND b<$upr;"
13895bad4c7Sdrh}
13995bad4c7Sdrhspeed_trial speed2-select1b [expr {50*50000}] row $sql
14095bad4c7Sdrh
14195bad4c7Sdrh# 50 SELECTs on an LIKE comparison.  There is no index so a full
14295bad4c7Sdrh# table scan is required.
14395bad4c7Sdrh#
14495bad4c7Sdrhset sql {}
14595bad4c7Sdrhfor {set i 0} {$i<50} {incr i} {
14695bad4c7Sdrh  append sql \
14795bad4c7Sdrh    "SELECT count(*), avg(b) FROM t1 WHERE c LIKE '%[number_name $i]%';"
14895bad4c7Sdrh}
14995bad4c7Sdrhspeed_trial speed2-select2b [expr {50*50000}] row $sql
150e4dd73b4Sdrh
151e4dd73b4Sdrh# Create indices
152e4dd73b4Sdrh#
153e4dd73b4Sdrhdb eval BEGIN
15491c58e23Sdrhspeed_trial speed2-createidx 150000 row {
155e4dd73b4Sdrh  CREATE INDEX i1a ON t1(a);
156e4dd73b4Sdrh  CREATE INDEX i1b ON t1(b);
157e4dd73b4Sdrh  CREATE INDEX i1c ON t1(c);
158e4dd73b4Sdrh}
159e4dd73b4Sdrhdb eval COMMIT
160e4dd73b4Sdrh
161e4dd73b4Sdrh# 5000 SELECTs on an integer comparison where the integer is
162e4dd73b4Sdrh# indexed.
163e4dd73b4Sdrh#
164e4dd73b4Sdrhset sql {}
165e4dd73b4Sdrhfor {set i 0} {$i<5000} {incr i} {
166e4dd73b4Sdrh  set lwr [expr {$i*100}]
167e4dd73b4Sdrh  set upr [expr {($i+10)*100}]
168e4dd73b4Sdrh  append sql "SELECT count(*), avg(b) FROM t1 WHERE b>=$lwr AND b<$upr;"
169e4dd73b4Sdrh}
17095bad4c7Sdrhspeed_trial speed2-select3a 5000 stmt $sql
171e4dd73b4Sdrh
172e4dd73b4Sdrh# 100000 random SELECTs against rowid.
173e4dd73b4Sdrh#
174e4dd73b4Sdrhset sql {}
175e4dd73b4Sdrhfor {set i 1} {$i<=100000} {incr i} {
176e4dd73b4Sdrh  set id [expr {int(rand()*50000)+1}]
177e4dd73b4Sdrh  append sql "SELECT c=='hi' FROM t1 WHERE rowid=$id;\n"
178e4dd73b4Sdrh}
17995bad4c7Sdrhspeed_trial speed2-select4a 100000 row $sql
180e4dd73b4Sdrh
181e4dd73b4Sdrh# 100000 random SELECTs against a unique indexed column.
182e4dd73b4Sdrh#
183e4dd73b4Sdrhset sql {}
184e4dd73b4Sdrhfor {set i 1} {$i<=100000} {incr i} {
185e4dd73b4Sdrh  set id [expr {int(rand()*50000)+1}]
186e4dd73b4Sdrh  append sql "SELECT c FROM t1 WHERE a=$id;"
187e4dd73b4Sdrh}
18895bad4c7Sdrhspeed_trial speed2-select5a 100000 row $sql
189e4dd73b4Sdrh
190e4dd73b4Sdrh# 50000 random SELECTs against an indexed column text column
191e4dd73b4Sdrh#
192e4dd73b4Sdrhset sql {}
193e4dd73b4Sdrhdb eval {SELECT c FROM t1 ORDER BY random() LIMIT 50000} {
194e4dd73b4Sdrh  append sql "SELECT c FROM t1 WHERE c='$c';"
195e4dd73b4Sdrh}
19695bad4c7Sdrhspeed_trial speed2-select6a 50000 row $sql
197e4dd73b4Sdrh
198e4dd73b4Sdrh# Vacuum
19995bad4c7Sdrhspeed_trial speed2-vacuum2 100000 row VACUUM
20095bad4c7Sdrh
20195bad4c7Sdrh
20295bad4c7Sdrh# 5000 SELECTs on an integer comparison where the integer is
20395bad4c7Sdrh# indexed.
20495bad4c7Sdrh#
20595bad4c7Sdrhset sql {}
20695bad4c7Sdrhfor {set i 0} {$i<5000} {incr i} {
20795bad4c7Sdrh  set lwr [expr {$i*100}]
20895bad4c7Sdrh  set upr [expr {($i+10)*100}]
20995bad4c7Sdrh  append sql "SELECT count(*), avg(b) FROM t1 WHERE b>=$lwr AND b<$upr;"
21095bad4c7Sdrh}
21195bad4c7Sdrhspeed_trial speed2-select3b 5000 stmt $sql
21295bad4c7Sdrh
21395bad4c7Sdrh# 100000 random SELECTs against rowid.
21495bad4c7Sdrh#
21595bad4c7Sdrhset sql {}
21695bad4c7Sdrhfor {set i 1} {$i<=100000} {incr i} {
21795bad4c7Sdrh  set id [expr {int(rand()*50000)+1}]
21895bad4c7Sdrh  append sql "SELECT c=='hi' FROM t1 WHERE rowid=$id;\n"
21995bad4c7Sdrh}
22095bad4c7Sdrhspeed_trial speed2-select4b 100000 row $sql
22195bad4c7Sdrh
22295bad4c7Sdrh# 100000 random SELECTs against a unique indexed column.
22395bad4c7Sdrh#
22495bad4c7Sdrhset sql {}
22595bad4c7Sdrhfor {set i 1} {$i<=100000} {incr i} {
22695bad4c7Sdrh  set id [expr {int(rand()*50000)+1}]
22795bad4c7Sdrh  append sql "SELECT c FROM t1 WHERE a=$id;"
22895bad4c7Sdrh}
22995bad4c7Sdrhspeed_trial speed2-select5b 100000 row $sql
23095bad4c7Sdrh
23195bad4c7Sdrh# 50000 random SELECTs against an indexed column text column
23295bad4c7Sdrh#
23395bad4c7Sdrhset sql {}
23495bad4c7Sdrhdb eval {SELECT c FROM t1 ORDER BY random() LIMIT 50000} {
23595bad4c7Sdrh  append sql "SELECT c FROM t1 WHERE c='$c';"
23695bad4c7Sdrh}
23795bad4c7Sdrhspeed_trial speed2-select6b 50000 row $sql
238e4dd73b4Sdrh
239e4dd73b4Sdrh# 5000 updates of ranges where the field being compared is indexed.
240e4dd73b4Sdrh#
241e4dd73b4Sdrhset sql {}
242e4dd73b4Sdrhfor {set i 0} {$i<5000} {incr i} {
243e4dd73b4Sdrh  set lwr [expr {$i*2}]
244e4dd73b4Sdrh  set upr [expr {($i+1)*2}]
245e4dd73b4Sdrh  append sql "UPDATE t1 SET b=b*2 WHERE a>=$lwr AND a<$upr;"
246e4dd73b4Sdrh}
247e4dd73b4Sdrhdb eval BEGIN
24891c58e23Sdrhspeed_trial speed2-update1 5000 stmt $sql
249e4dd73b4Sdrhdb eval COMMIT
250e4dd73b4Sdrh
251e4dd73b4Sdrh# 50000 single-row updates.  An index is used to find the row quickly.
252e4dd73b4Sdrh#
253e4dd73b4Sdrhset sql {}
254e4dd73b4Sdrhfor {set i 0} {$i<50000} {incr i} {
255e4dd73b4Sdrh  set r [expr {int(rand()*500000)}]
256e4dd73b4Sdrh  append sql "UPDATE t1 SET b=$r WHERE a=$i;"
257e4dd73b4Sdrh}
258e4dd73b4Sdrhdb eval BEGIN
25991c58e23Sdrhspeed_trial speed2-update2 50000 row $sql
260e4dd73b4Sdrhdb eval COMMIT
261e4dd73b4Sdrh
262e4dd73b4Sdrh# 1 big text update that touches every row in the table.
263e4dd73b4Sdrh#
26491c58e23Sdrhspeed_trial speed2-update3 50000 row {
265e4dd73b4Sdrh  UPDATE t1 SET c=a;
266e4dd73b4Sdrh}
267e4dd73b4Sdrh
268e4dd73b4Sdrh# Many individual text updates.  Each row in the table is
269e4dd73b4Sdrh# touched through an index.
270e4dd73b4Sdrh#
271e4dd73b4Sdrhset sql {}
272e4dd73b4Sdrhfor {set i 1} {$i<=50000} {incr i} {
273e4dd73b4Sdrh  set r [expr {int(rand()*500000)}]
274e4dd73b4Sdrh  append sql "UPDATE t1 SET c='[number_name $r]' WHERE a=$i;"
275e4dd73b4Sdrh}
276e4dd73b4Sdrhdb eval BEGIN
27791c58e23Sdrhspeed_trial speed2-update4 50000 row $sql
278e4dd73b4Sdrhdb eval COMMIT
279e4dd73b4Sdrh
280e4dd73b4Sdrh# Delete all content in a table.
281e4dd73b4Sdrh#
28291c58e23Sdrhspeed_trial speed2-delete1 50000 row {DELETE FROM t1}
283e4dd73b4Sdrh
284e4dd73b4Sdrh# Copy one table into another
285e4dd73b4Sdrh#
28691c58e23Sdrhspeed_trial speed2-copy1 50000 row {INSERT INTO t1 SELECT * FROM t2}
287e4dd73b4Sdrh
288e4dd73b4Sdrh# Delete all content in a table, one row at a time.
289e4dd73b4Sdrh#
29091c58e23Sdrhspeed_trial speed2-delete2 50000 row {DELETE FROM t1 WHERE 1}
291e4dd73b4Sdrh
292e4dd73b4Sdrh# Refill the table yet again
293e4dd73b4Sdrh#
29491c58e23Sdrhspeed_trial speed2-copy2 50000 row {INSERT INTO t1 SELECT * FROM t2}
295e4dd73b4Sdrh
296e4dd73b4Sdrh# Drop the table and recreate it without its indices.
297e4dd73b4Sdrh#
298e4dd73b4Sdrhdb eval BEGIN
29991c58e23Sdrhspeed_trial speed2-drop1 50000 row {
300e4dd73b4Sdrh   DROP TABLE t1;
301e4dd73b4Sdrh   CREATE TABLE t1(a INTEGER, b INTEGER, c TEXT);
302e4dd73b4Sdrh}
303e4dd73b4Sdrhdb eval COMMIT
304e4dd73b4Sdrh
305e4dd73b4Sdrh# Refill the table yet again.  This copy should be faster because
306e4dd73b4Sdrh# there are no indices to deal with.
307e4dd73b4Sdrh#
30891c58e23Sdrhspeed_trial speed2-copy3 50000 row {INSERT INTO t1 SELECT * FROM t2}
309e4dd73b4Sdrh
310e4dd73b4Sdrh# Select 20000 rows from the table at random.
311e4dd73b4Sdrh#
31291c58e23Sdrhspeed_trial speed2-random1 50000 row {
313e4dd73b4Sdrh  SELECT rowid FROM t1 ORDER BY random() LIMIT 20000
314e4dd73b4Sdrh}
315e4dd73b4Sdrh
316e4dd73b4Sdrh# Delete 20000 random rows from the table.
317e4dd73b4Sdrh#
31891c58e23Sdrhspeed_trial speed2-random-del1 20000 row {
319e4dd73b4Sdrh  DELETE FROM t1 WHERE rowid IN
320e4dd73b4Sdrh    (SELECT rowid FROM t1 ORDER BY random() LIMIT 20000)
321e4dd73b4Sdrh}
32291c58e23Sdrhdo_test speed2-1.1 {
323e4dd73b4Sdrh  db one {SELECT count(*) FROM t1}
324e4dd73b4Sdrh} 30000
325e4dd73b4Sdrh
326e4dd73b4Sdrh
327e4dd73b4Sdrh# Delete 20000 more rows at random from the table.
328e4dd73b4Sdrh#
32991c58e23Sdrhspeed_trial speed2-random-del2 20000 row {
330e4dd73b4Sdrh  DELETE FROM t1 WHERE rowid IN
331e4dd73b4Sdrh    (SELECT rowid FROM t1 ORDER BY random() LIMIT 20000)
332e4dd73b4Sdrh}
33391c58e23Sdrhdo_test speed2-1.2 {
334e4dd73b4Sdrh  db one {SELECT count(*) FROM t1}
335e4dd73b4Sdrh} 10000
336dd92431aSdrhspeed_trial_summary speed2
337dd92431aSdrh
338e4dd73b4Sdrh
339e4dd73b4Sdrhfinish_test
340