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