Random thought: You might squeeze some more performance out by
trying a couple different filesystems. i.e. if you're using ext3,
try some different journaling options, or try ext2.
--- Al Danial <[EMAIL PROTECTED]> wrote:
> A scientific application I work with has clumsy data retrieval
> options. I dumped the application's output--integer and floating
> point numbers--into an SQLite database and soon after began to
> enjoy the power of SQL to pull out interesting results.
>
> The main complaint for making the transfer to SQLite a permanent
> part of our solution is the time it takes to insert the numbers
> into a database. It takes about a minute to insert 24 million
> numbers into three tables. Most database people (including me)
> would be thrilled to see this kind of insert performance but
> my colleagues are asking if it can be sped up.
>
> The attached C program measures insert performance for populating
> a table with an integer and three random floating point values with
> user defined transaction size. Usage is:
>
> ./sqlite_insert <number of rows> <transaction size>
>
> It writes to the hardcoded database file /tmp/a.db
> On my Dell Precision 360, Pentium4 3.0 GHz, 1 GB RAM, IDE disk
> drive, ext3, RHEL v3, Linux kernel 2.4.21, I peak out around 121,000
> inserts/second using a transaction size of 20,000:
> ./sqlite_insert 100000 20000
> 100000 inserts to /tmp/a.db in 0.829 s = 120626.53 inserts/s
>
> Performance drops a bit when I increase the number of rows to
> two million (a typical size for my application):
>
> ./sqlite_insert 2000000 50000
> 2000000 inserts to /tmp/a.db in 17.124 s = 116795.07 inserts/s
>
> What kind of insert performance do you see on your machine? If it
> is substantially better than 120 kinserts/s what kind of hardware
> do you have? I'm especially interested in how much faster the
> code runs on systems with multiple disks in a RAID 0 configuration.
> Are there other tricks to speeding insert performance? Is it even
> reasonable to ask for more? -- Al
> > /*
> [EMAIL PROTECTED]
>
> # sample build:
> gcc -o sqlite_insert sqlite_insert.c \
> -L/usr/local/sqlite-3.2.1/lib -lsqlite3
> -I/usr/local/sqlite-3.2.1/include
>
> # sample run:
> ./sqlite_insert 100000 50000
>
> */
>
>
> #include <sqlite3.h>
> #include <stdlib.h> /* RAND_MAX */
> #include <sys/time.h> /* timeval, gettimeofday() */
>
>
> int sql_begin(sqlite3 *db) { /* {{{1 */
> char *errmsg;
> if (sqlite3_exec(db, "BEGIN TRANSACTION",
> NULL, NULL, &errmsg) != SQLITE_OK) {
> printf("couldn't begin transaction: %s\n", errmsg);
> return 0;
> } else {
> return 1;
> }
> } /* 1}}} */
> int sql_commit(sqlite3 *db) { /* {{{1 */
> char *errmsg;
> if (sqlite3_exec(db, "COMMIT TRANSACTION",
> NULL, NULL, &errmsg) != SQLITE_OK) {
> printf("couldn't commit transaction: %s\n", errmsg);
> return 0;
> } else {
> return 1;
> }
> } /* 1}}} */
> float elapsed(struct timeval start, struct timeval end) { /* {{{1 */
> return (float) (end.tv_sec - start.tv_sec ) +
> ((float) (end.tv_usec - start.tv_usec)/1000000);
> } /* 1}}} */
>
>
> int main(int argc, char *argv[]) {
> const char *zLeftover;
> #define CMD_SIZE 1000
> char rm_command[CMD_SIZE],
> *errmsg, *dbfile = "/tmp/a.db";
> /* *dbfile = ":memory:" is faster, but not of interest */
> int rc, i, N, xact_size, n_this_xact = 0;
> double x, y, z;
> float delta_T;
> struct timeval start_time, end_time;
> sqlite3 *db;
> sqlite3_stmt *Stmt;
>
>
> if (argc < 3) {
> printf("\nUsage: %s <N> <X>\n\n", argv[0]);
> printf("\tInsert <N> rows into a table of an SQLite database\n");
> printf("\tusing transaction sizes of <X>.\n");
> printf("\tThe table has four columns of numeric data:\n");
> printf("\t field_1 integer\n");
> printf("\t field_2 float\n");
> printf("\t field_3 float\n");
> printf("\t field_4 float\n");
> printf("\tThe integer field will have values 1..<N> while the\n");
> printf("\tdouble precision values are random on [-50.0, 50.0]\n");
> exit(0);
> }
> N = atoi(argv[1]);
> xact_size = atoi(argv[2]);
> snprintf(rm_command, CMD_SIZE-1, "rm -f %s", dbfile);
> system(rm_command); /* the database file must not exist before
> calling sqlite3_open() and trying to insert */
>
>
> gettimeofday(&start_time, 0);
>
>
> rc = sqlite3_open(dbfile, &db);
>
>
> sql_begin(db);
> rc = sqlite3_prepare(db, "create table table_name(field_1 integer primary
> key,"
> "field_2 float, "
> "field_3 float, "
> "field_4 float)",
> -1, &Stmt, &zLeftover);
> rc = sqlite3_step(Stmt);
> rc = sqlite3_finalize(Stmt);
>
>
> rc = sqlite3_prepare(db, "insert into table_name values(?,?,?,?)",
> -1, &Stmt, &zLeftover);
>
>
> for (i = 0; i < N; i++) {
> x = 50.0 - (100.0*rand()/(RAND_MAX+1.0));
> y = 50.0 - (100.0*rand()/(RAND_MAX+1.0));
> z = 50.0 - (100.0*rand()/(RAND_MAX+1.0));
> rc = sqlite3_bind_int( Stmt, 1, i);
> rc = sqlite3_bind_double(Stmt, 2, x);
> rc = sqlite3_bind_double(Stmt, 3, y);
> rc = sqlite3_bind_double(Stmt, 4, z);
> rc = sqlite3_step(Stmt);
> rc = sqlite3_reset(Stmt);
> ++n_this_xact;
> if (!(n_this_xact % xact_size)) {
> /* have done xact_size inserts, finish this
> * transaction and start a new one */
> sql_commit(db);
> sql_begin( db);
> n_this_xact = 0;
> }
> }
> sql_commit(db);
> sqlite3_close(db);
>
> gettimeofday(&end_time, 0);
> delta_T = elapsed(start_time, end_time);
> printf(" %d inserts to %s in %.3f s = %.2f inserts/s\n",
> N, dbfile, delta_T, N/delta_T);
>
> return 0;
> }
>
__________________________________
Do you Yahoo!?
Yahoo! Small Business - Try our new resources site!
http://smallbusiness.yahoo.com/resources/