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 

Reply via email to