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