xref: /sqlite-3.40.0/test/speed1p.explain (revision 4c68e6d2)
1*4c68e6d2Sdrh# 2008 March 21
2*4c68e6d2Sdrh#
3*4c68e6d2Sdrh# The author disclaims copyright to this source code.  In place of
4*4c68e6d2Sdrh# a legal notice, here is a blessing:
5*4c68e6d2Sdrh#
6*4c68e6d2Sdrh#    May you do good and not evil.
7*4c68e6d2Sdrh#    May you find forgiveness for yourself and forgive others.
8*4c68e6d2Sdrh#    May you share freely, never taking more than you give.
9*4c68e6d2Sdrh#
10*4c68e6d2Sdrh#*************************************************************************
11*4c68e6d2Sdrh# This file implements regression tests for SQLite library.  The
12*4c68e6d2Sdrh# focus of this script is measuring executing speed.
13*4c68e6d2Sdrh#
14*4c68e6d2Sdrh# This is a copy of speed1.test modified to user prepared statements.
15*4c68e6d2Sdrh#
16*4c68e6d2Sdrh# $Id: speed1p.explain,v 1.1 2008/04/16 12:57:48 drh Exp $
17*4c68e6d2Sdrh#
18*4c68e6d2Sdrh
19*4c68e6d2Sdrhset testdir [file dirname $argv0]
20*4c68e6d2Sdrhsource $testdir/tester.tcl
21*4c68e6d2Sdrhspeed_trial_init speed1
22*4c68e6d2Sdrh
23*4c68e6d2Sdrh# Set a uniform random seed
24*4c68e6d2Sdrhexpr srand(0)
25*4c68e6d2Sdrh
26*4c68e6d2Sdrhset sqlout [open speed1.txt w]
27*4c68e6d2Sdrhproc tracesql {sql} {
28*4c68e6d2Sdrh  puts $::sqlout $sql\;
29*4c68e6d2Sdrh}
30*4c68e6d2Sdrh#db trace tracesql
31*4c68e6d2Sdrh
32*4c68e6d2Sdrh# The number_name procedure below converts its argment (an integer)
33*4c68e6d2Sdrh# into a string which is the English-language name for that number.
34*4c68e6d2Sdrh#
35*4c68e6d2Sdrh# Example:
36*4c68e6d2Sdrh#
37*4c68e6d2Sdrh#     puts [number_name 123]   ->  "one hundred twenty three"
38*4c68e6d2Sdrh#
39*4c68e6d2Sdrhset ones {zero one two three four five six seven eight nine
40*4c68e6d2Sdrh          ten eleven twelve thirteen fourteen fifteen sixteen seventeen
41*4c68e6d2Sdrh          eighteen nineteen}
42*4c68e6d2Sdrhset tens {{} ten twenty thirty forty fifty sixty seventy eighty ninety}
43*4c68e6d2Sdrhproc number_name {n} {
44*4c68e6d2Sdrh  if {$n>=1000} {
45*4c68e6d2Sdrh    set txt "[number_name [expr {$n/1000}]] thousand"
46*4c68e6d2Sdrh    set n [expr {$n%1000}]
47*4c68e6d2Sdrh  } else {
48*4c68e6d2Sdrh    set txt {}
49*4c68e6d2Sdrh  }
50*4c68e6d2Sdrh  if {$n>=100} {
51*4c68e6d2Sdrh    append txt " [lindex $::ones [expr {$n/100}]] hundred"
52*4c68e6d2Sdrh    set n [expr {$n%100}]
53*4c68e6d2Sdrh  }
54*4c68e6d2Sdrh  if {$n>=20} {
55*4c68e6d2Sdrh    append txt " [lindex $::tens [expr {$n/10}]]"
56*4c68e6d2Sdrh    set n [expr {$n%10}]
57*4c68e6d2Sdrh  }
58*4c68e6d2Sdrh  if {$n>0} {
59*4c68e6d2Sdrh    append txt " [lindex $::ones $n]"
60*4c68e6d2Sdrh  }
61*4c68e6d2Sdrh  set txt [string trim $txt]
62*4c68e6d2Sdrh  if {$txt==""} {set txt zero}
63*4c68e6d2Sdrh  return $txt
64*4c68e6d2Sdrh}
65*4c68e6d2Sdrh
66*4c68e6d2Sdrh# Create a database schema.
67*4c68e6d2Sdrh#
68*4c68e6d2Sdrhdo_test speed1p-1.0 {
69*4c68e6d2Sdrh  execsql {
70*4c68e6d2Sdrh    PRAGMA page_size=1024;
71*4c68e6d2Sdrh    PRAGMA cache_size=8192;
72*4c68e6d2Sdrh    PRAGMA locking_mode=EXCLUSIVE;
73*4c68e6d2Sdrh    CREATE TABLE t1(a INTEGER, b INTEGER, c TEXT);
74*4c68e6d2Sdrh    CREATE TABLE t2(a INTEGER, b INTEGER, c TEXT);
75*4c68e6d2Sdrh    CREATE INDEX i2a ON t2(a);
76*4c68e6d2Sdrh    CREATE INDEX i2b ON t2(b);
77*4c68e6d2Sdrh  }
78*4c68e6d2Sdrh  execsql {
79*4c68e6d2Sdrh    SELECT name FROM sqlite_master ORDER BY 1;
80*4c68e6d2Sdrh  }
81*4c68e6d2Sdrh} {i2a i2b t1 t2}
82*4c68e6d2Sdrh
83*4c68e6d2Sdrh
84*4c68e6d2Sdrh# 50000 INSERTs on an unindexed table
85*4c68e6d2Sdrh#
86*4c68e6d2Sdrhset list {}
87*4c68e6d2Sdrhfor {set i 1} {$i<=50000} {incr i} {
88*4c68e6d2Sdrh  set r [expr {int(rand()*500000)}]
89*4c68e6d2Sdrh  set x [number_name $r]
90*4c68e6d2Sdrh  lappend list $i $r $x
91*4c68e6d2Sdrh}
92*4c68e6d2Sdrhset script {
93*4c68e6d2Sdrh  foreach {i r x} $::list {
94*4c68e6d2Sdrh    db eval {INSERT INTO t1 VALUES($i,$r,$x)}
95*4c68e6d2Sdrh  }
96*4c68e6d2Sdrh}
97*4c68e6d2Sdrhexplain {INSERT INTO t1 VALUES($i,$r,$x)}
98*4c68e6d2Sdrhdb eval BEGIN
99*4c68e6d2Sdrhspeed_trial_tcl speed1p-insert1 50000 row $script
100*4c68e6d2Sdrhdb eval COMMIT
101*4c68e6d2Sdrh
102*4c68e6d2Sdrh# 50000 INSERTs on an indexed table
103*4c68e6d2Sdrh#
104*4c68e6d2Sdrhset list {}
105*4c68e6d2Sdrhfor {set i 1} {$i<=50000} {incr i} {
106*4c68e6d2Sdrh  set r [expr {int(rand()*500000)}]
107*4c68e6d2Sdrh  set x [number_name $r]
108*4c68e6d2Sdrh  lappend list $i $r $x
109*4c68e6d2Sdrh}
110*4c68e6d2Sdrhset script {
111*4c68e6d2Sdrh  foreach {i r x} $::list {
112*4c68e6d2Sdrh    db eval {INSERT INTO t2 VALUES($i,$r,$x)}
113*4c68e6d2Sdrh  }
114*4c68e6d2Sdrh}
115*4c68e6d2Sdrhexplain {INSERT INTO t2 VALUES($i,$r,$x)}
116*4c68e6d2Sdrhdb eval BEGIN
117*4c68e6d2Sdrhspeed_trial_tcl speed1p-insert2 50000 row $script
118*4c68e6d2Sdrhdb eval COMMIT
119*4c68e6d2Sdrh
120*4c68e6d2Sdrh
121*4c68e6d2Sdrh
122*4c68e6d2Sdrh# 50 SELECTs on an integer comparison.  There is no index so
123*4c68e6d2Sdrh# a full table scan is required.
124*4c68e6d2Sdrh#
125*4c68e6d2Sdrhset list {}
126*4c68e6d2Sdrhfor {set i 0} {$i<50} {incr i} {
127*4c68e6d2Sdrh  set lwr [expr {$i*100}]
128*4c68e6d2Sdrh  set upr [expr {($i+10)*100}]
129*4c68e6d2Sdrh  lappend list $lwr $upr
130*4c68e6d2Sdrh}
131*4c68e6d2Sdrhset script {
132*4c68e6d2Sdrh  foreach {lwr upr} $::list {
133*4c68e6d2Sdrh    db eval  {SELECT count(*), avg(b) FROM t1 WHERE b>=$lwr AND b<$upr}
134*4c68e6d2Sdrh  }
135*4c68e6d2Sdrh}
136*4c68e6d2Sdrhexplain {SELECT count(*), avg(b) FROM t1 WHERE b>=$lwr AND b<$upr}
137*4c68e6d2Sdrhdb eval BEGIN
138*4c68e6d2Sdrhspeed_trial_tcl speed1p-select1 [expr {50*50000}] row $script
139*4c68e6d2Sdrhdb eval COMMIT
140*4c68e6d2Sdrh
141*4c68e6d2Sdrh# 50 SELECTs on an LIKE comparison.  There is no index so a full
142*4c68e6d2Sdrh# table scan is required.
143*4c68e6d2Sdrh#
144*4c68e6d2Sdrhset list {}
145*4c68e6d2Sdrhfor {set i 0} {$i<50} {incr i} {
146*4c68e6d2Sdrh  lappend list "%[number_name $i]%"
147*4c68e6d2Sdrh}
148*4c68e6d2Sdrhset script {
149*4c68e6d2Sdrh  foreach pattern $::list {
150*4c68e6d2Sdrh    db eval {SELECT count(*), avg(b) FROM t1 WHERE c LIKE $pattern}
151*4c68e6d2Sdrh  }
152*4c68e6d2Sdrh}
153*4c68e6d2Sdrhexplain {SELECT count(*), avg(b) FROM t1 WHERE c LIKE $pattern}
154*4c68e6d2Sdrhdb eval BEGIN
155*4c68e6d2Sdrhspeed_trial_tcl speed1p-select2 [expr {50*50000}] row $script
156*4c68e6d2Sdrhdb eval COMMIT
157*4c68e6d2Sdrh
158*4c68e6d2Sdrh# Create indices
159*4c68e6d2Sdrh#
160*4c68e6d2Sdrhexplain {CREATE INDEX i1a ON t1(a)}
161*4c68e6d2Sdrhexplain {CREATE INDEX i1b ON t1(b)}
162*4c68e6d2Sdrhdb eval BEGIN
163*4c68e6d2Sdrhspeed_trial speed1p-createidx 150000 row {
164*4c68e6d2Sdrh  CREATE INDEX i1a ON t1(a);
165*4c68e6d2Sdrh  CREATE INDEX i1b ON t1(b);
166*4c68e6d2Sdrh  CREATE INDEX i1c ON t1(c);
167*4c68e6d2Sdrh}
168*4c68e6d2Sdrhdb eval COMMIT
169*4c68e6d2Sdrh
170*4c68e6d2Sdrh# 5000 SELECTs on an integer comparison where the integer is
171*4c68e6d2Sdrh# indexed.
172*4c68e6d2Sdrh#
173*4c68e6d2Sdrhset list {}
174*4c68e6d2Sdrhfor {set i 0} {$i<5000} {incr i} {
175*4c68e6d2Sdrh  set lwr [expr {$i*100}]
176*4c68e6d2Sdrh  set upr [expr {($i+10)*100}]
177*4c68e6d2Sdrh  lappend list $lwr $upr
178*4c68e6d2Sdrh}
179*4c68e6d2Sdrhset script {
180*4c68e6d2Sdrh  foreach {lwr upr} $::list {
181*4c68e6d2Sdrh    db eval {SELECT count(*), avg(b) FROM t1 WHERE b>=$lwr AND b<$upr}
182*4c68e6d2Sdrh  }
183*4c68e6d2Sdrh}
184*4c68e6d2Sdrhexplain {SELECT count(*), avg(b) FROM t1 WHERE b>=$lwr AND b<$upr}
185*4c68e6d2Sdrhdb eval BEGIN
186*4c68e6d2Sdrhspeed_trial_tcl speed1p-select3 5000 stmt $script
187*4c68e6d2Sdrhdb eval COMMIT
188*4c68e6d2Sdrh
189*4c68e6d2Sdrh# 100000 random SELECTs against rowid.
190*4c68e6d2Sdrh#
191*4c68e6d2Sdrhset list {}
192*4c68e6d2Sdrhfor {set i 1} {$i<=100000} {incr i} {
193*4c68e6d2Sdrh  set id [expr {int(rand()*50000)+1}]
194*4c68e6d2Sdrh  lappend list $id
195*4c68e6d2Sdrh}
196*4c68e6d2Sdrhset script {
197*4c68e6d2Sdrh  foreach id $::list {
198*4c68e6d2Sdrh    db eval {SELECT c FROM t1 WHERE rowid=$id}
199*4c68e6d2Sdrh  }
200*4c68e6d2Sdrh}
201*4c68e6d2Sdrhexplain {SELECT c FROM t1 WHERE rowid=$id}
202*4c68e6d2Sdrhdb eval BEGIN
203*4c68e6d2Sdrhspeed_trial_tcl speed1p-select4 100000 row $script
204*4c68e6d2Sdrhdb eval COMMIT
205*4c68e6d2Sdrh
206*4c68e6d2Sdrh# 100000 random SELECTs against a unique indexed column.
207*4c68e6d2Sdrh#
208*4c68e6d2Sdrhset list {}
209*4c68e6d2Sdrhfor {set i 1} {$i<=100000} {incr i} {
210*4c68e6d2Sdrh  set id [expr {int(rand()*50000)+1}]
211*4c68e6d2Sdrh  lappend list $id
212*4c68e6d2Sdrh}
213*4c68e6d2Sdrhset script {
214*4c68e6d2Sdrh  foreach id $::list {
215*4c68e6d2Sdrh    db eval {SELECT c FROM t1 WHERE a=$id}
216*4c68e6d2Sdrh  }
217*4c68e6d2Sdrh}
218*4c68e6d2Sdrhexplain {SELECT c FROM t1 WHERE a=$id}
219*4c68e6d2Sdrhdb eval BEGIN
220*4c68e6d2Sdrhspeed_trial_tcl speed1p-select5 100000 row $script
221*4c68e6d2Sdrhdb eval COMMIT
222*4c68e6d2Sdrh
223*4c68e6d2Sdrh# 50000 random SELECTs against an indexed column text column
224*4c68e6d2Sdrh#
225*4c68e6d2Sdrhset list [db eval {SELECT c FROM t1 ORDER BY random() LIMIT 50000}]
226*4c68e6d2Sdrhset script {
227*4c68e6d2Sdrh  foreach c $::list {
228*4c68e6d2Sdrh    db eval {SELECT c FROM t1 WHERE c=$c}
229*4c68e6d2Sdrh  }
230*4c68e6d2Sdrh}
231*4c68e6d2Sdrhexplain {SELECT c FROM t1 WHERE c=$c}
232*4c68e6d2Sdrhdb eval BEGIN
233*4c68e6d2Sdrhspeed_trial_tcl speed1p-select6 50000 row $script
234*4c68e6d2Sdrhdb eval COMMIT
235*4c68e6d2Sdrh
236*4c68e6d2Sdrh
237*4c68e6d2Sdrh# Vacuum
238*4c68e6d2Sdrhspeed_trial speed1p-vacuum 100000 row VACUUM
239*4c68e6d2Sdrh
240*4c68e6d2Sdrh# 5000 updates of ranges where the field being compared is indexed.
241*4c68e6d2Sdrh#
242*4c68e6d2Sdrhset list {}
243*4c68e6d2Sdrhfor {set i 0} {$i<5000} {incr i} {
244*4c68e6d2Sdrh  set lwr [expr {$i*2}]
245*4c68e6d2Sdrh  set upr [expr {($i+1)*2}]
246*4c68e6d2Sdrh  lappend list $lwr $upr
247*4c68e6d2Sdrh}
248*4c68e6d2Sdrhset script {
249*4c68e6d2Sdrh  foreach {lwr upr} $::list {
250*4c68e6d2Sdrh    db eval {UPDATE t1 SET b=b*2 WHERE a>=$lwr AND a<$upr}
251*4c68e6d2Sdrh  }
252*4c68e6d2Sdrh}
253*4c68e6d2Sdrhexplain {UPDATE t1 SET b=b*2 WHERE a>=$lwr AND a<$upr}
254*4c68e6d2Sdrhdb eval BEGIN
255*4c68e6d2Sdrhspeed_trial_tcl speed1p-update1 5000 stmt $script
256*4c68e6d2Sdrhdb eval COMMIT
257*4c68e6d2Sdrh
258*4c68e6d2Sdrh# 50000 single-row updates.  An index is used to find the row quickly.
259*4c68e6d2Sdrh#
260*4c68e6d2Sdrhset list {}
261*4c68e6d2Sdrhfor {set i 0} {$i<50000} {incr i} {
262*4c68e6d2Sdrh  set r [expr {int(rand()*500000)}]
263*4c68e6d2Sdrh  lappend list $i $r
264*4c68e6d2Sdrh}
265*4c68e6d2Sdrhset script {
266*4c68e6d2Sdrh  foreach {i r} $::list {
267*4c68e6d2Sdrh    db eval {UPDATE t1 SET b=$r WHERE a=$i}
268*4c68e6d2Sdrh  }
269*4c68e6d2Sdrh}
270*4c68e6d2Sdrhexplain {UPDATE t1 SET b=$r WHERE a=$i}
271*4c68e6d2Sdrhdb eval BEGIN
272*4c68e6d2Sdrhspeed_trial_tcl speed1p-update2 50000 row $script
273*4c68e6d2Sdrhdb eval COMMIT
274*4c68e6d2Sdrh
275*4c68e6d2Sdrh# 1 big text update that touches every row in the table.
276*4c68e6d2Sdrh#
277*4c68e6d2Sdrhexplain {UPDATE t1 SET c=a}
278*4c68e6d2Sdrhspeed_trial speed1p-update3 50000 row {
279*4c68e6d2Sdrh  UPDATE t1 SET c=a;
280*4c68e6d2Sdrh}
281*4c68e6d2Sdrh
282*4c68e6d2Sdrh# Many individual text updates.  Each row in the table is
283*4c68e6d2Sdrh# touched through an index.
284*4c68e6d2Sdrh#
285*4c68e6d2Sdrhset list {}
286*4c68e6d2Sdrhfor {set i 1} {$i<=50000} {incr i} {
287*4c68e6d2Sdrh  set r [expr {int(rand()*500000)}]
288*4c68e6d2Sdrh  lappend list $i [number_name $r]
289*4c68e6d2Sdrh}
290*4c68e6d2Sdrhset script {
291*4c68e6d2Sdrh  foreach {i x} $::list {
292*4c68e6d2Sdrh    db eval {UPDATE t1 SET c=$x WHERE a=$i}
293*4c68e6d2Sdrh  }
294*4c68e6d2Sdrh}
295*4c68e6d2Sdrhexplain {UPDATE t1 SET c=$x WHERE a=$i}
296*4c68e6d2Sdrhdb eval BEGIN
297*4c68e6d2Sdrhspeed_trial_tcl speed1p-update4 50000 row $script
298*4c68e6d2Sdrhdb eval COMMIT
299*4c68e6d2Sdrh
300*4c68e6d2Sdrh# Delete all content in a table.
301*4c68e6d2Sdrh#
302*4c68e6d2Sdrhexplain {DELETE FROM t1}
303*4c68e6d2Sdrhspeed_trial speed1p-delete1 50000 row {DELETE FROM t1}
304*4c68e6d2Sdrh
305*4c68e6d2Sdrh# Copy one table into another
306*4c68e6d2Sdrh#
307*4c68e6d2Sdrhexplain {INSERT INTO t1 SELECT * FROM t2}
308*4c68e6d2Sdrhspeed_trial speed1p-copy1 50000 row {INSERT INTO t1 SELECT * FROM t2}
309*4c68e6d2Sdrh
310*4c68e6d2Sdrh# Delete all content in a table, one row at a time.
311*4c68e6d2Sdrh#
312*4c68e6d2Sdrhexplain {DELETE FROM t1 WHERE 1}
313*4c68e6d2Sdrhspeed_trial speed1p-delete2 50000 row {DELETE FROM t1 WHERE 1}
314*4c68e6d2Sdrh
315*4c68e6d2Sdrh# Refill the table yet again
316*4c68e6d2Sdrh#
317*4c68e6d2Sdrhspeed_trial speed1p-copy2 50000 row {INSERT INTO t1 SELECT * FROM t2}
318*4c68e6d2Sdrh
319*4c68e6d2Sdrh# Drop the table and recreate it without its indices.
320*4c68e6d2Sdrh#
321*4c68e6d2Sdrhexplain {DROP TABLE t1}
322*4c68e6d2Sdrhexplain {CREATE TABLE tX(a INTEGER, b INTEGER, c TEXT)}
323*4c68e6d2Sdrhdb eval BEGIN
324*4c68e6d2Sdrhspeed_trial speed1p-drop1 50000 row {
325*4c68e6d2Sdrh   DROP TABLE t1;
326*4c68e6d2Sdrh   CREATE TABLE t1(a INTEGER, b INTEGER, c TEXT);
327*4c68e6d2Sdrh}
328*4c68e6d2Sdrhdb eval COMMIT
329*4c68e6d2Sdrh
330*4c68e6d2Sdrh# Refill the table yet again.  This copy should be faster because
331*4c68e6d2Sdrh# there are no indices to deal with.
332*4c68e6d2Sdrh#
333*4c68e6d2Sdrhspeed_trial speed1p-copy3 50000 row {INSERT INTO t1 SELECT * FROM t2}
334*4c68e6d2Sdrh
335*4c68e6d2Sdrh# Select 20000 rows from the table at random.
336*4c68e6d2Sdrh#
337*4c68e6d2Sdrhexplain {SELECT rowid FROM t1 ORDER BY random() LIMIT 20000}
338*4c68e6d2Sdrhspeed_trial speed1p-random1 50000 row {
339*4c68e6d2Sdrh  SELECT rowid FROM t1 ORDER BY random() LIMIT 20000
340*4c68e6d2Sdrh}
341*4c68e6d2Sdrh
342*4c68e6d2Sdrh# Delete 20000 random rows from the table.
343*4c68e6d2Sdrh#
344*4c68e6d2Sdrhexplain {DELETE FROM t1 WHERE rowid IN
345*4c68e6d2Sdrh    (SELECT rowid FROM t1 ORDER BY random() LIMIT 20000)}
346*4c68e6d2Sdrhspeed_trial speed1p-random-del1 20000 row {
347*4c68e6d2Sdrh  DELETE FROM t1 WHERE rowid IN
348*4c68e6d2Sdrh    (SELECT rowid FROM t1 ORDER BY random() LIMIT 20000)
349*4c68e6d2Sdrh}
350*4c68e6d2Sdrhdo_test speed1p-1.1 {
351*4c68e6d2Sdrh  db one {SELECT count(*) FROM t1}
352*4c68e6d2Sdrh} 30000
353*4c68e6d2Sdrh
354*4c68e6d2Sdrh
355*4c68e6d2Sdrh# Delete 20000 more rows at random from the table.
356*4c68e6d2Sdrh#
357*4c68e6d2Sdrhspeed_trial speed1p-random-del2 20000 row {
358*4c68e6d2Sdrh  DELETE FROM t1 WHERE rowid IN
359*4c68e6d2Sdrh    (SELECT rowid FROM t1 ORDER BY random() LIMIT 20000)
360*4c68e6d2Sdrh}
361*4c68e6d2Sdrhdo_test speed1p-1.2 {
362*4c68e6d2Sdrh  db one {SELECT count(*) FROM t1}
363*4c68e6d2Sdrh} 10000
364*4c68e6d2Sdrhspeed_trial_summary speed1
365*4c68e6d2Sdrh
366*4c68e6d2Sdrhfinish_test
367