danielk1977 | 63c64f3 | 2007-05-17 14:45:12 +0000 | [diff] [blame] | 1 | # 2007 May 17 |
| 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 testing that the overflow-page related |
| 13 | # enhancements added after version 3.3.17 speed things up. |
| 14 | # |
shane | 20a35fd | 2009-07-09 02:48:23 +0000 | [diff] [blame] | 15 | # $Id: speed3.test,v 1.6 2009/07/09 02:48:24 shane Exp $ |
danielk1977 | 63c64f3 | 2007-05-17 14:45:12 +0000 | [diff] [blame] | 16 | # |
| 17 | |
| 18 | #--------------------------------------------------------------------- |
| 19 | # Test plan: |
| 20 | # |
| 21 | # If auto-vacuum is enabled for the database, the following cases |
| 22 | # should show performance improvement with respect to 3.3.17. |
| 23 | # |
| 24 | # + When deleting rows that span overflow pages. This is faster |
| 25 | # because the overflow pages no longer need to be read before |
| 26 | # they can be moved to the free list (test cases speed3-1.X). |
| 27 | # |
| 28 | # + When reading a column value stored on an overflow page that |
| 29 | # is not the first overflow page for the row. The improvement |
| 30 | # in this case is because the overflow pages between the tree |
| 31 | # page and the overflow page containing the value do not have |
| 32 | # to be read (test cases speed3-2.X). |
| 33 | # |
| 34 | |
| 35 | set testdir [file dirname $argv0] |
| 36 | source $testdir/tester.tcl |
danielk1977 | 4152e67 | 2007-09-12 17:01:45 +0000 | [diff] [blame] | 37 | |
danielk1977 | 5a8f937 | 2007-10-09 08:29:32 +0000 | [diff] [blame] | 38 | ifcapable !tclvar||!attach { |
danielk1977 | 4152e67 | 2007-09-12 17:01:45 +0000 | [diff] [blame] | 39 | finish_test |
| 40 | return |
| 41 | } |
| 42 | |
danielk1977 | 63c64f3 | 2007-05-17 14:45:12 +0000 | [diff] [blame] | 43 | speed_trial_init speed1 |
| 44 | |
| 45 | # Set a uniform random seed |
| 46 | expr srand(0) |
| 47 | |
| 48 | set ::NROW 1000 |
| 49 | |
| 50 | # The number_name procedure below converts its argment (an integer) |
| 51 | # into a string which is the English-language name for that number. |
| 52 | # |
| 53 | # Example: |
| 54 | # |
| 55 | # puts [number_name 123] -> "one hundred twenty three" |
| 56 | # |
| 57 | set ones {zero one two three four five six seven eight nine |
| 58 | ten eleven twelve thirteen fourteen fifteen sixteen seventeen |
| 59 | eighteen nineteen} |
| 60 | set tens {{} ten twenty thirty forty fifty sixty seventy eighty ninety} |
| 61 | proc number_name {n} { |
| 62 | if {$n>=1000} { |
| 63 | set txt "[number_name [expr {$n/1000}]] thousand" |
| 64 | set n [expr {$n%1000}] |
| 65 | } else { |
| 66 | set txt {} |
| 67 | } |
| 68 | if {$n>=100} { |
| 69 | append txt " [lindex $::ones [expr {$n/100}]] hundred" |
| 70 | set n [expr {$n%100}] |
| 71 | } |
| 72 | if {$n>=20} { |
| 73 | append txt " [lindex $::tens [expr {$n/10}]]" |
| 74 | set n [expr {$n%10}] |
| 75 | } |
| 76 | if {$n>0} { |
| 77 | append txt " [lindex $::ones $n]" |
| 78 | } |
| 79 | set txt [string trim $txt] |
| 80 | if {$txt==""} {set txt zero} |
| 81 | return $txt |
| 82 | } |
| 83 | |
| 84 | proc populate_t1 {db} { |
| 85 | $db transaction { |
| 86 | for {set ii 0} {$ii < $::NROW} {incr ii} { |
| 87 | set N [number_name $ii] |
| 88 | set repeats [expr {(10000/[string length $N])+1}] |
| 89 | set text [string range [string repeat $N $repeats] 0 10000] |
| 90 | $db eval {INSERT INTO main.t1 VALUES($ii, $text, $ii)} |
| 91 | } |
| 92 | $db eval {INSERT INTO aux.t1 SELECT * FROM main.t1} |
| 93 | } |
| 94 | } |
| 95 | |
| 96 | |
| 97 | proc io_log {db} { |
drh | 2764170 | 2007-08-22 02:56:42 +0000 | [diff] [blame] | 98 | db_enter db |
danielk1977 | 63c64f3 | 2007-05-17 14:45:12 +0000 | [diff] [blame] | 99 | array set stats1 [btree_pager_stats [btree_from_db db]] |
| 100 | array set stats2 [btree_pager_stats [btree_from_db db 2]] |
drh | 2764170 | 2007-08-22 02:56:42 +0000 | [diff] [blame] | 101 | db_leave db |
danielk1977 | 63c64f3 | 2007-05-17 14:45:12 +0000 | [diff] [blame] | 102 | # puts "1: [array get stats1]" |
| 103 | # puts "2: [array get stats2]" |
| 104 | puts "Incrvacuum: Read $stats1(read), wrote $stats1(write)" |
| 105 | puts "Normal : Read $stats2(read), wrote $stats2(write)" |
| 106 | } |
| 107 | |
mistachkin | 8e16b2d | 2016-08-26 04:32:59 +0000 | [diff] [blame] | 108 | proc speed3_reset_db {} { |
danielk1977 | 63c64f3 | 2007-05-17 14:45:12 +0000 | [diff] [blame] | 109 | db close |
| 110 | sqlite3 db test.db |
| 111 | db eval { |
| 112 | PRAGMA main.cache_size = 200000; |
| 113 | PRAGMA main.auto_vacuum = 'incremental'; |
| 114 | ATTACH 'test2.db' AS 'aux'; |
| 115 | PRAGMA aux.auto_vacuum = 'none'; |
| 116 | } |
| 117 | } |
| 118 | |
mistachkin | fda06be | 2011-08-02 00:57:34 +0000 | [diff] [blame] | 119 | forcedelete test2.db test2.db-journal |
mistachkin | 8e16b2d | 2016-08-26 04:32:59 +0000 | [diff] [blame] | 120 | speed3_reset_db |
danielk1977 | 63c64f3 | 2007-05-17 14:45:12 +0000 | [diff] [blame] | 121 | |
| 122 | # Set up a database in auto-vacuum mode and create a database schema. |
| 123 | # |
| 124 | do_test speed3-0.1 { |
| 125 | execsql { |
| 126 | CREATE TABLE main.t1(a INTEGER, b TEXT, c INTEGER); |
| 127 | } |
| 128 | execsql { |
| 129 | SELECT name FROM sqlite_master ORDER BY 1; |
| 130 | } |
| 131 | } {t1} |
| 132 | do_test speed3-0.2 { |
| 133 | execsql { |
| 134 | CREATE TABLE aux.t1(a INTEGER, b TEXT, c INTEGER); |
| 135 | } |
| 136 | execsql { |
| 137 | SELECT name FROM aux.sqlite_master ORDER BY 1; |
| 138 | } |
| 139 | } {t1} |
| 140 | do_test speed3-0.3 { |
| 141 | populate_t1 db |
| 142 | execsql { |
| 143 | SELECT count(*) FROM main.t1; |
| 144 | SELECT count(*) FROM aux.t1; |
| 145 | } |
| 146 | } "$::NROW $::NROW" |
| 147 | do_test speed3-0.4 { |
| 148 | execsql { |
| 149 | PRAGMA main.auto_vacuum; |
| 150 | PRAGMA aux.auto_vacuum; |
| 151 | } |
| 152 | } {2 0} |
| 153 | |
| 154 | # Delete all content in a table, one row at a time. |
| 155 | # |
| 156 | #io_log db |
mistachkin | 8e16b2d | 2016-08-26 04:32:59 +0000 | [diff] [blame] | 157 | speed3_reset_db |
danielk1977 | 63c64f3 | 2007-05-17 14:45:12 +0000 | [diff] [blame] | 158 | speed_trial speed3-1.incrvacuum $::NROW row {DELETE FROM main.t1 WHERE 1} |
| 159 | speed_trial speed3-1.normal $::NROW row {DELETE FROM aux.t1 WHERE 1} |
| 160 | io_log db |
| 161 | |
| 162 | # Select the "C" column (located at the far end of the overflow |
| 163 | # chain) from each table row. |
| 164 | # |
danielk1977 | b39f70b | 2007-05-17 18:28:11 +0000 | [diff] [blame] | 165 | #db eval {PRAGMA incremental_vacuum(500000)} |
danielk1977 | 63c64f3 | 2007-05-17 14:45:12 +0000 | [diff] [blame] | 166 | populate_t1 db |
mistachkin | 8e16b2d | 2016-08-26 04:32:59 +0000 | [diff] [blame] | 167 | speed3_reset_db |
danielk1977 | 63c64f3 | 2007-05-17 14:45:12 +0000 | [diff] [blame] | 168 | speed_trial speed3-2.incrvacuum $::NROW row {SELECT c FROM main.t1} |
| 169 | speed_trial speed3-2.normal $::NROW row {SELECT c FROM aux.t1} |
| 170 | io_log db |
| 171 | |
| 172 | finish_test |