1*c5c4113dSnw141292 2*c5c4113dSnw141292#pragma ident "%Z%%M% %I% %E% SMI" 3*c5c4113dSnw141292 4*c5c4113dSnw141292#!/usr/bin/tclsh 5*c5c4113dSnw141292# 6*c5c4113dSnw141292# Run this script using TCLSH to do a speed comparison between 7*c5c4113dSnw141292# various versions of SQLite and PostgreSQL and MySQL 8*c5c4113dSnw141292# 9*c5c4113dSnw141292 10*c5c4113dSnw141292# Run a test 11*c5c4113dSnw141292# 12*c5c4113dSnw141292set cnt 1 13*c5c4113dSnw141292proc runtest {title} { 14*c5c4113dSnw141292 global cnt 15*c5c4113dSnw141292 set sqlfile test$cnt.sql 16*c5c4113dSnw141292 puts "<h2>Test $cnt: $title</h2>" 17*c5c4113dSnw141292 incr cnt 18*c5c4113dSnw141292 set fd [open $sqlfile r] 19*c5c4113dSnw141292 set sql [string trim [read $fd [file size $sqlfile]]] 20*c5c4113dSnw141292 close $fd 21*c5c4113dSnw141292 set sx [split $sql \n] 22*c5c4113dSnw141292 set n [llength $sx] 23*c5c4113dSnw141292 if {$n>8} { 24*c5c4113dSnw141292 set sql {} 25*c5c4113dSnw141292 for {set i 0} {$i<3} {incr i} {append sql [lindex $sx $i]<br>\n} 26*c5c4113dSnw141292 append sql "<i>... [expr {$n-6}] lines omitted</i><br>\n" 27*c5c4113dSnw141292 for {set i [expr {$n-3}]} {$i<$n} {incr i} { 28*c5c4113dSnw141292 append sql [lindex $sx $i]<br>\n 29*c5c4113dSnw141292 } 30*c5c4113dSnw141292 } else { 31*c5c4113dSnw141292 regsub -all \n [string trim $sql] <br> sql 32*c5c4113dSnw141292 } 33*c5c4113dSnw141292 puts "<blockquote>" 34*c5c4113dSnw141292 puts "$sql" 35*c5c4113dSnw141292 puts "</blockquote><table border=0 cellpadding=0 cellspacing=0>" 36*c5c4113dSnw141292 set format {<tr><td>%s</td><td align="right"> %.3f</td></tr>} 37*c5c4113dSnw141292 set delay 1000 38*c5c4113dSnw141292# exec sync; after $delay; 39*c5c4113dSnw141292# set t [time "exec psql drh <$sqlfile" 1] 40*c5c4113dSnw141292# set t [expr {[lindex $t 0]/1000000.0}] 41*c5c4113dSnw141292# puts [format $format PostgreSQL: $t] 42*c5c4113dSnw141292 exec sync; after $delay; 43*c5c4113dSnw141292 set t [time "exec mysql -f drh <$sqlfile" 1] 44*c5c4113dSnw141292 set t [expr {[lindex $t 0]/1000000.0}] 45*c5c4113dSnw141292 puts [format $format MySQL: $t] 46*c5c4113dSnw141292# set t [time "exec ./sqlite232 s232.db <$sqlfile" 1] 47*c5c4113dSnw141292# set t [expr {[lindex $t 0]/1000000.0}] 48*c5c4113dSnw141292# puts [format $format {SQLite 2.3.2:} $t] 49*c5c4113dSnw141292# set t [time "exec ./sqlite-100 s100.db <$sqlfile" 1] 50*c5c4113dSnw141292# set t [expr {[lindex $t 0]/1000000.0}] 51*c5c4113dSnw141292# puts [format $format {SQLite 2.4 (cache=100):} $t] 52*c5c4113dSnw141292 exec sync; after $delay; 53*c5c4113dSnw141292 set t [time "exec ./sqlite248 s2k.db <$sqlfile" 1] 54*c5c4113dSnw141292 set t [expr {[lindex $t 0]/1000000.0}] 55*c5c4113dSnw141292 puts [format $format {SQLite 2.4.8:} $t] 56*c5c4113dSnw141292 exec sync; after $delay; 57*c5c4113dSnw141292 set t [time "exec ./sqlite248 sns.db <$sqlfile" 1] 58*c5c4113dSnw141292 set t [expr {[lindex $t 0]/1000000.0}] 59*c5c4113dSnw141292 puts [format $format {SQLite 2.4.8 (nosync):} $t] 60*c5c4113dSnw141292 exec sync; after $delay; 61*c5c4113dSnw141292 set t [time "exec ./sqlite2412 s2kb.db <$sqlfile" 1] 62*c5c4113dSnw141292 set t [expr {[lindex $t 0]/1000000.0}] 63*c5c4113dSnw141292 puts [format $format {SQLite 2.4.12:} $t] 64*c5c4113dSnw141292 exec sync; after $delay; 65*c5c4113dSnw141292 set t [time "exec ./sqlite2412 snsb.db <$sqlfile" 1] 66*c5c4113dSnw141292 set t [expr {[lindex $t 0]/1000000.0}] 67*c5c4113dSnw141292 puts [format $format {SQLite 2.4.12 (nosync):} $t] 68*c5c4113dSnw141292# set t [time "exec ./sqlite-t1 st1.db <$sqlfile" 1] 69*c5c4113dSnw141292# set t [expr {[lindex $t 0]/1000000.0}] 70*c5c4113dSnw141292# puts [format $format {SQLite 2.4 (test):} $t] 71*c5c4113dSnw141292 puts "</table>" 72*c5c4113dSnw141292} 73*c5c4113dSnw141292 74*c5c4113dSnw141292# Initialize the environment 75*c5c4113dSnw141292# 76*c5c4113dSnw141292expr srand(1) 77*c5c4113dSnw141292catch {exec /bin/sh -c {rm -f s*.db}} 78*c5c4113dSnw141292set fd [open clear.sql w] 79*c5c4113dSnw141292puts $fd { 80*c5c4113dSnw141292 drop table t1; 81*c5c4113dSnw141292 drop table t2; 82*c5c4113dSnw141292} 83*c5c4113dSnw141292close $fd 84*c5c4113dSnw141292catch {exec psql drh <clear.sql} 85*c5c4113dSnw141292catch {exec mysql drh <clear.sql} 86*c5c4113dSnw141292set fd [open 2kinit.sql w] 87*c5c4113dSnw141292puts $fd { 88*c5c4113dSnw141292 PRAGMA default_cache_size=2000; 89*c5c4113dSnw141292 PRAGMA default_synchronous=on; 90*c5c4113dSnw141292} 91*c5c4113dSnw141292close $fd 92*c5c4113dSnw141292exec ./sqlite248 s2k.db <2kinit.sql 93*c5c4113dSnw141292exec ./sqlite2412 s2kb.db <2kinit.sql 94*c5c4113dSnw141292set fd [open nosync-init.sql w] 95*c5c4113dSnw141292puts $fd { 96*c5c4113dSnw141292 PRAGMA default_cache_size=2000; 97*c5c4113dSnw141292 PRAGMA default_synchronous=off; 98*c5c4113dSnw141292} 99*c5c4113dSnw141292close $fd 100*c5c4113dSnw141292exec ./sqlite248 sns.db <nosync-init.sql 101*c5c4113dSnw141292exec ./sqlite2412 snsb.db <nosync-init.sql 102*c5c4113dSnw141292set ones {zero one two three four five six seven eight nine 103*c5c4113dSnw141292 ten eleven twelve thirteen fourteen fifteen sixteen seventeen 104*c5c4113dSnw141292 eighteen nineteen} 105*c5c4113dSnw141292set tens {{} ten twenty thirty forty fifty sixty seventy eighty ninety} 106*c5c4113dSnw141292proc number_name {n} { 107*c5c4113dSnw141292 if {$n>=1000} { 108*c5c4113dSnw141292 set txt "[number_name [expr {$n/1000}]] thousand" 109*c5c4113dSnw141292 set n [expr {$n%1000}] 110*c5c4113dSnw141292 } else { 111*c5c4113dSnw141292 set txt {} 112*c5c4113dSnw141292 } 113*c5c4113dSnw141292 if {$n>=100} { 114*c5c4113dSnw141292 append txt " [lindex $::ones [expr {$n/100}]] hundred" 115*c5c4113dSnw141292 set n [expr {$n%100}] 116*c5c4113dSnw141292 } 117*c5c4113dSnw141292 if {$n>=20} { 118*c5c4113dSnw141292 append txt " [lindex $::tens [expr {$n/10}]]" 119*c5c4113dSnw141292 set n [expr {$n%10}] 120*c5c4113dSnw141292 } 121*c5c4113dSnw141292 if {$n>0} { 122*c5c4113dSnw141292 append txt " [lindex $::ones $n]" 123*c5c4113dSnw141292 } 124*c5c4113dSnw141292 set txt [string trim $txt] 125*c5c4113dSnw141292 if {$txt==""} {set txt zero} 126*c5c4113dSnw141292 return $txt 127*c5c4113dSnw141292} 128*c5c4113dSnw141292 129*c5c4113dSnw141292 130*c5c4113dSnw141292 131*c5c4113dSnw141292set fd [open test$cnt.sql w] 132*c5c4113dSnw141292puts $fd "CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100));" 133*c5c4113dSnw141292for {set i 1} {$i<=1000} {incr i} { 134*c5c4113dSnw141292 set r [expr {int(rand()*100000)}] 135*c5c4113dSnw141292 puts $fd "INSERT INTO t1 VALUES($i,$r,'[number_name $r]');" 136*c5c4113dSnw141292} 137*c5c4113dSnw141292close $fd 138*c5c4113dSnw141292runtest {1000 INSERTs} 139*c5c4113dSnw141292 140*c5c4113dSnw141292 141*c5c4113dSnw141292 142*c5c4113dSnw141292set fd [open test$cnt.sql w] 143*c5c4113dSnw141292puts $fd "BEGIN;" 144*c5c4113dSnw141292puts $fd "CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100));" 145*c5c4113dSnw141292for {set i 1} {$i<=25000} {incr i} { 146*c5c4113dSnw141292 set r [expr {int(rand()*500000)}] 147*c5c4113dSnw141292 puts $fd "INSERT INTO t2 VALUES($i,$r,'[number_name $r]');" 148*c5c4113dSnw141292} 149*c5c4113dSnw141292puts $fd "COMMIT;" 150*c5c4113dSnw141292close $fd 151*c5c4113dSnw141292runtest {25000 INSERTs in a transaction} 152*c5c4113dSnw141292 153*c5c4113dSnw141292 154*c5c4113dSnw141292 155*c5c4113dSnw141292set fd [open test$cnt.sql w] 156*c5c4113dSnw141292for {set i 0} {$i<100} {incr i} { 157*c5c4113dSnw141292 set lwr [expr {$i*100}] 158*c5c4113dSnw141292 set upr [expr {($i+10)*100}] 159*c5c4113dSnw141292 puts $fd "SELECT count(*), avg(b) FROM t2 WHERE b>=$lwr AND b<$upr;" 160*c5c4113dSnw141292} 161*c5c4113dSnw141292close $fd 162*c5c4113dSnw141292runtest {100 SELECTs without an index} 163*c5c4113dSnw141292 164*c5c4113dSnw141292 165*c5c4113dSnw141292 166*c5c4113dSnw141292set fd [open test$cnt.sql w] 167*c5c4113dSnw141292for {set i 1} {$i<=100} {incr i} { 168*c5c4113dSnw141292 puts $fd "SELECT count(*), avg(b) FROM t2 WHERE c LIKE '%[number_name $i]%';" 169*c5c4113dSnw141292} 170*c5c4113dSnw141292close $fd 171*c5c4113dSnw141292runtest {100 SELECTs on a string comparison} 172*c5c4113dSnw141292 173*c5c4113dSnw141292 174*c5c4113dSnw141292 175*c5c4113dSnw141292set fd [open test$cnt.sql w] 176*c5c4113dSnw141292puts $fd {CREATE INDEX i2a ON t2(a);} 177*c5c4113dSnw141292puts $fd {CREATE INDEX i2b ON t2(b);} 178*c5c4113dSnw141292close $fd 179*c5c4113dSnw141292runtest {Creating an index} 180*c5c4113dSnw141292 181*c5c4113dSnw141292 182*c5c4113dSnw141292 183*c5c4113dSnw141292set fd [open test$cnt.sql w] 184*c5c4113dSnw141292for {set i 0} {$i<5000} {incr i} { 185*c5c4113dSnw141292 set lwr [expr {$i*100}] 186*c5c4113dSnw141292 set upr [expr {($i+1)*100}] 187*c5c4113dSnw141292 puts $fd "SELECT count(*), avg(b) FROM t2 WHERE b>=$lwr AND b<$upr;" 188*c5c4113dSnw141292} 189*c5c4113dSnw141292close $fd 190*c5c4113dSnw141292runtest {5000 SELECTs with an index} 191*c5c4113dSnw141292 192*c5c4113dSnw141292 193*c5c4113dSnw141292 194*c5c4113dSnw141292set fd [open test$cnt.sql w] 195*c5c4113dSnw141292puts $fd "BEGIN;" 196*c5c4113dSnw141292for {set i 0} {$i<1000} {incr i} { 197*c5c4113dSnw141292 set lwr [expr {$i*10}] 198*c5c4113dSnw141292 set upr [expr {($i+1)*10}] 199*c5c4113dSnw141292 puts $fd "UPDATE t1 SET b=b*2 WHERE a>=$lwr AND a<$upr;" 200*c5c4113dSnw141292} 201*c5c4113dSnw141292puts $fd "COMMIT;" 202*c5c4113dSnw141292close $fd 203*c5c4113dSnw141292runtest {1000 UPDATEs without an index} 204*c5c4113dSnw141292 205*c5c4113dSnw141292 206*c5c4113dSnw141292 207*c5c4113dSnw141292set fd [open test$cnt.sql w] 208*c5c4113dSnw141292puts $fd "BEGIN;" 209*c5c4113dSnw141292for {set i 1} {$i<=25000} {incr i} { 210*c5c4113dSnw141292 set r [expr {int(rand()*500000)}] 211*c5c4113dSnw141292 puts $fd "UPDATE t2 SET b=$r WHERE a=$i;" 212*c5c4113dSnw141292} 213*c5c4113dSnw141292puts $fd "COMMIT;" 214*c5c4113dSnw141292close $fd 215*c5c4113dSnw141292runtest {25000 UPDATEs with an index} 216*c5c4113dSnw141292 217*c5c4113dSnw141292 218*c5c4113dSnw141292set fd [open test$cnt.sql w] 219*c5c4113dSnw141292puts $fd "BEGIN;" 220*c5c4113dSnw141292for {set i 1} {$i<=25000} {incr i} { 221*c5c4113dSnw141292 set r [expr {int(rand()*500000)}] 222*c5c4113dSnw141292 puts $fd "UPDATE t2 SET c='[number_name $r]' WHERE a=$i;" 223*c5c4113dSnw141292} 224*c5c4113dSnw141292puts $fd "COMMIT;" 225*c5c4113dSnw141292close $fd 226*c5c4113dSnw141292runtest {25000 text UPDATEs with an index} 227*c5c4113dSnw141292 228*c5c4113dSnw141292 229*c5c4113dSnw141292 230*c5c4113dSnw141292set fd [open test$cnt.sql w] 231*c5c4113dSnw141292puts $fd "BEGIN;" 232*c5c4113dSnw141292puts $fd "INSERT INTO t1 SELECT * FROM t2;" 233*c5c4113dSnw141292puts $fd "INSERT INTO t2 SELECT * FROM t1;" 234*c5c4113dSnw141292puts $fd "COMMIT;" 235*c5c4113dSnw141292close $fd 236*c5c4113dSnw141292runtest {INSERTs from a SELECT} 237*c5c4113dSnw141292 238*c5c4113dSnw141292 239*c5c4113dSnw141292 240*c5c4113dSnw141292set fd [open test$cnt.sql w] 241*c5c4113dSnw141292puts $fd {DELETE FROM t2 WHERE c LIKE '%fifty%';} 242*c5c4113dSnw141292close $fd 243*c5c4113dSnw141292runtest {DELETE without an index} 244*c5c4113dSnw141292 245*c5c4113dSnw141292 246*c5c4113dSnw141292 247*c5c4113dSnw141292set fd [open test$cnt.sql w] 248*c5c4113dSnw141292puts $fd {DELETE FROM t2 WHERE a>10 AND a<20000;} 249*c5c4113dSnw141292close $fd 250*c5c4113dSnw141292runtest {DELETE with an index} 251*c5c4113dSnw141292 252*c5c4113dSnw141292 253*c5c4113dSnw141292 254*c5c4113dSnw141292set fd [open test$cnt.sql w] 255*c5c4113dSnw141292puts $fd {INSERT INTO t2 SELECT * FROM t1;} 256*c5c4113dSnw141292close $fd 257*c5c4113dSnw141292runtest {A big INSERT after a big DELETE} 258*c5c4113dSnw141292 259*c5c4113dSnw141292 260*c5c4113dSnw141292 261*c5c4113dSnw141292set fd [open test$cnt.sql w] 262*c5c4113dSnw141292puts $fd {BEGIN;} 263*c5c4113dSnw141292puts $fd {DELETE FROM t1;} 264*c5c4113dSnw141292for {set i 1} {$i<=3000} {incr i} { 265*c5c4113dSnw141292 set r [expr {int(rand()*100000)}] 266*c5c4113dSnw141292 puts $fd "INSERT INTO t1 VALUES($i,$r,'[number_name $r]');" 267*c5c4113dSnw141292} 268*c5c4113dSnw141292puts $fd {COMMIT;} 269*c5c4113dSnw141292close $fd 270*c5c4113dSnw141292runtest {A big DELETE followed by many small INSERTs} 271*c5c4113dSnw141292 272*c5c4113dSnw141292 273*c5c4113dSnw141292 274*c5c4113dSnw141292set fd [open test$cnt.sql w] 275*c5c4113dSnw141292puts $fd {DROP TABLE t1;} 276*c5c4113dSnw141292puts $fd {DROP TABLE t2;} 277*c5c4113dSnw141292close $fd 278*c5c4113dSnw141292runtest {DROP TABLE} 279