What happens if you wrap the SELECT statements in a transaction in the same way as you have the INSERTs?
--- William Hachfeld <[EMAIL PROTECTED]> wrote: > > Heh everyone! > > Can anyone explain to me why SQLite shows such poor query performance when the > database is located on an NFS-mounted file system? When running with a single > process accessing the database, I'm finding that my insertion rates are > similar > to local disk, but my query performance is much, much, slower. > > To illustrate, I built my test code (source at the end of this post) as: > > g++ -o sqlite-test sqlite-test.cxx -lsqlite3 -lrt > > using GCC 3.3.3. My Dell test system had a 3.2Ghz P4, 1Gb of RAM, and a 80 ATA > HD (2Mb cache). I'm running SuSE 9.1 on this system. I ran each test three > times: > > > /tmp 36749.3, 36662.5, 36239.8 Insertions/Second > /tmp 264.195, 268.678, 266.233 Queries/Second > > ~ 36515.5, 36538.9, 36673.6 Insertions/Second > ~ 274.449, 273.875, 273.236 Queries/Second > > NFS(1) 37128.2, 37479, 37347.9 Insertions/Second > NFS(1) 44.2276, 45.408, 52.3626 Queries/Second > > NFS(2) 36812.2, 37272.3, 36595.2 Insertions/Second > NFS(2) 68.3878, 68.3142, 68.0701 Queries/Second > > > /tmp: Local "tmpfs" file system > ~: Local "reiserfs" file system > NFS(1): Served from Origin 2000 16p system, RAID-5 SCSI disk array, > fairly > heavy user load > NFS(2): Served from lowly PIII Linux system, local ATA disk, no user load > > > Note that insertion performance is basically the same across all > configurations, but the query performance is seriously degraded when running > on > NFS. In practice, on our real application, I'm seeing as much as a 50x speedup > when moving the database from NFS onto the local disk. Colleagues working on > the same project have all seen similar results. > > Does anyone have an idea why this is the case? Is there anything I can do to > improve the query performance on NFS-mounted databases? Since we are using > SQLite for storing our application's "save files", our users are going to want > to be able to locate the database in a directory of their choosing. > > Also note that I'm not complaining about SQLite's query performance in > general. > The absolute numbers in this test case are artifically low because I'm forcing > a full table scan by querying on a non-indexed field. My concern is with the > relative performance between local versus NFS file systems. > > Thanks guys! > > -- William Hachfeld > > > > > > #include <assert.h> > #include <inttypes.h> > #include <iostream> > #include <sqlite3.h> > #include <stdio.h> > #include <stdlib.h> > #include <string> > #include <time.h> > #include <unistd.h> > > uint64_t Now() > { > struct timespec now; > assert(clock_gettime(CLOCK_REALTIME, &now) == 0); > return (static_cast<uint64_t>(now.tv_sec) * 1000000000) + > static_cast<uint64_t>(now.tv_nsec); > } > > int main(int argc, char* argv[]) > { > const int N = 10000; > > // Form and display the name of the database > std::string dbname = std::string(get_current_dir_name()) + "/tmp.db"; > std::cout << "Database \"" << dbname << "\"" << std::endl; > > // Open the database > sqlite3* handle = NULL; > assert(sqlite3_open(dbname.c_str(), &handle) == SQLITE_OK); > assert(handle != NULL); > > // Create and populate a table with 'N' entries > > assert(sqlite3_exec(handle, "BEGIN TRANSACTION;", > NULL, NULL, NULL) == SQLITE_OK); > > assert(sqlite3_exec(handle, > "CREATE TABLE Test (" > " key INTEGER PRIMARY KEY," > " value INTEGER" > ");", > NULL, NULL, NULL) == SQLITE_OK); > > uint64_t t_start = Now(); > for(int i = 0; i < N; ++i) { > char* statement = > sqlite3_mprintf("INSERT INTO Test (value) VALUES (%ld);", i); > assert(statement != NULL); > assert(sqlite3_exec(handle, statement, NULL, NULL, NULL) == SQLITE_OK); > sqlite3_free(statement); > } > uint64_t t_stop = Now(); > > assert(sqlite3_exec(handle, "COMMIT TRANSACTION;", > NULL, NULL, NULL) == SQLITE_OK); > > std::cout << (static_cast<double>(N) / > (static_cast<double>(t_stop - t_start) / 1000000000.0)) > << " Insertions/Second" << std::endl; > > // Perform 'N' queries on the table > > t_start = Now(); > for(int i = 0; i < N; ++i) { > char* statement = > sqlite3_mprintf("SELECT * FROM Test WHERE value = %ld;", i); > assert(statement != NULL); > assert(sqlite3_exec(handle, statement, NULL, NULL, NULL) == SQLITE_OK); > sqlite3_free(statement); > } > t_stop = Now(); > > std::cout << (static_cast<double>(N) / > (static_cast<double>(t_stop - t_start) / 1000000000.0)) > << " Queries/Second" << std::endl << std::endl; > > // Close the database > assert(sqlite3_close(handle) == SQLITE_OK); > > // Remove the database > assert(remove(dbname.c_str()) == 0); > } > __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com