I've encountered an unusual problem with SQLite performance under Windows and am hoping someone might have an idea of what might be happening.

We are developing a Delphi application which uses SQLite compiled into the program. During one round of tests we discovered a section of code which was executing a number of INSERTS outside of the context of a transaction. The issue reported to me was that this section of code was running extremely slowly. When I researched the issue, I could not replicate the slowdown. After several hours of experimentation, here is my summary:

We tested the procedure under performance analysis on seven different Windows machines, ranging from Windows 2000, Windows XP and Vista. In five of the cases, inserting 128 rows outside of the context of a transaction takes 11 - 17 seconds. In the other two cases, a Windows XP machine and a Windows 2000 machine running under VMWare, the exact same operation takes between 0.8 and 1.1 seconds.

To eliminate hardware specific issues, I copied the VMWare W2K machine to one of the "slower" machines, a Windows XP laptop. The VM ran the operation in roughly 1.2 seconds. The host machine reports 15 seconds for the exact same operation.

Antivirus is identical on five of the example machines. Indexing Service is disabled on all machines. One of the "slower" units in question is a state of the art, quad core machine.

I decided to isolate the issue from our application by creating a small Ruby program which uses the 3.14 dll. The code is below:

--------
require 'dbi'
require 'sqlite3'
require 'benchmark'


db = SQLite3::Database.new( "stest.sldb3" )

db.execute(<<eof
CREATE TABLE IF NOT EXISTS RESPONSES (
 RESPONSE_ID INTEGER PRIMARY KEY,
 SURVEY_ID INTEGER,
 QUESTIONNAIRE_ID TEXT,
 DATA_ELEMENT_NAME TEXT,
 CURRENT_VALUE VARCHAR(1000),
 FIRST_VALUE VARCHAR(1000)
);
eof
)

db.execute('CREATE UNIQUE INDEX RESPONSE_IDX1 ON RESPONSES (QUESTIONNAIRE_ID, DATA_ELEMENT_NAME);')

include Benchmark

bm(10) do |x|
 x.report("insert") {
   1000.times do |i|
db.execute("INSERT INTO RESPONSES VALUES (null, 1, 1, 'FOO#{i}', 'wibble, wobble, woo', null)")
   end
 }
end

--------

Execution time on my VM is:

               user     system      total        real
insert      0.093000   2.484000   2.577000 (  8.125000)

Execution time on the HP laptop is:

               user     system      total        real
insert      0.453000   1.828000   2.281000 (125.719000)

As we can see, the benchmarking indicates that SQLite itself is unlikely to be the culprit. Examination of task manager during operation shows 3% CPU time to Ruby in the slower case and 30% in the faster. The only other process receiving significant time is System Idle. Examination of task manager while executing our application on the different machines showed similar results.

As a concluding note, the section of code which initiated this research has already been enclosed in a start/end transaction. Therefore, the question at hand is not "how do I solve this specific performance problem" rather it is "what the heck is happening that is creating a better than order of magnitude difference in execution time on five out of seven Windows machines?".

Any suggestions for further investigation are appreciated.


John Elrick
Fenestra Technologies

-----------------------------------------------------------------------------
To unsubscribe, send email to [EMAIL PROTECTED]
-----------------------------------------------------------------------------

Reply via email to