OK...I added your trigger example as option 8.  And I had pasted the wrong 
version in my last email.  My timings were correct.  Your example also did 
sql_exec instead of using prepare so it will run slower.
I also made this compilable on Unix too.

On Unix my timing matches the run time and there are the right # of records in 
the database with the right values.  Unix is faster than Windows (8-core 2.6Ghz 
Unix system using SAS drives (I'm not sure of the model but I'm quite sure they 
are 7200RPM).
Perhaps this is write caching on the disk?

time ./batch 1600 1 0
1543.1
real    0m1.042s
user    0m0.046s
sys     0m0.216s

Something tells me your theory is wrong.  All 1600 records get inserted into 
the database in approx 1 second so it matches independent timing quite well.

Here's my results with your trigger.  I'll maintain the timings are correct 
until somebody can prove this wrong.  Your theory is simply incomplete and is 
not taking into account SQLite's behavior.

D:\SQLite>batch 504 1 0 -- simple single insert no batch
442.1
D:\SQLite>batch 504 1 8 -- with trigger insert on 2nd table -- single row
307.3
D:\SQLite>batch 504 1 9 -- trigger + in memory
5378.5
D:\SQLite>batch 504 1 10 -- trigger +  index
212.3
D:\SQLite>batch 504 1 12 -- trigger + WAL mode
2482.4
D:\SQLite>batch 504 1 14 -- trigger + WAL mode + index
461.0
D:\SQLite>batch 504 1 6 -- WAL mode + index
4608.0
D:\SQLite>batch 504 504 6 -- WAL mode + index in one transaction
32256.0
Of course you can't do your trigger (i.e. update) inside a transaction so 
there's some error checking for that now.
You trigger is a factor of 10 slower.  I think we determined before that doing 
that update directly instead of a trigger would be faster.  I should add a 
method for that too.

I also added a SYNCHRONOUS=OFF option#16
That speeds it up a bit too.  I didn't see where FULL made much of a difference 
here so I just made OFF the option.
D:\SQLite>batch 1600 1 0
414.6
D:\SQLite>batch 1600 1 0
279.8
D:\SQLite>batch 1600 1 16
602.4
D:\SQLite>batch 1600 1 16
572.1
D:\SQLite>batch 1600 1600 16
102400.0

#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
#include <windows.h>
#include <winbase.h>
#else
#include <sys/time.h>
#endif
#include <time.h>
#include "sqlite3.h"
double elapsed()
{
    double t1;
    struct timeval tv;
    static long base_seconds;
    gettimeofday(&tv,NULL);
    if (base_seconds==0) base_seconds=tv.tv_sec;
    return (tv.tv_sec-base_seconds)+tv.tv_usec/(double)1000000;
}
int AddTrigger(sqlite3 *db)
{
        char SqlTxt[256];
        int             rc;
        strcpy(SqlTxt,"CREATE TRIGGER XX AFTER INSERT ON t FOR EACH ROW BEGIN 
");
        strcat(SqlTxt,"UPDATE t2 SET n = NEW.i+1;");
        strcat(SqlTxt,"END;");
 rc = sqlite3_exec(db,SqlTxt,NULL,NULL,NULL);
        if (rc != SQLITE_OK) {
                puts(sqlite3_errmsg(db));
        }
        return(0);
}
int main(int argc, char *argv[])
{
 sqlite3 *db;
 sqlite3_stmt *stmt=NULL;
 int rc;
 int n=0;
 int nrec=0;
 int interval=0;
 int flags=0;
 double t1;
 if (argc != 4) {
  fprintf(stderr,"Usage: %s nrecords commit_interval flags\n",argv[0]);
  fprintf(stderr,"Flag 0 = simple table\n");
  fprintf(stderr,"Flag 1 = in-memory database\n");
  fprintf(stderr,"Flag 2 = add index\n");
  fprintf(stderr,"Flag 4 = WAL mode\n");
  fprintf(stderr,"Flag 8 = Add a trigger\n");
  fprintf(stderr,"Flag 16 = Synchronous=Off\n");
  fprintf(stderr,"Add flags to combine features\n");
  exit(-1);
 }
 nrec=atoi(argv[1]);
 interval=atoi(argv[2]);
 flags=atoi(argv[3]);
 if (flags & 1) {
  rc=sqlite3_open(":memory:",&db);
 }
 else {
  remove("batch.db");
  rc=sqlite3_open("batch.db",&db);
 }
 if (rc != SQLITE_OK) {
  puts(sqlite3_errmsg(db));
 }
 rc=sqlite3_exec(db,"create table t (i integer)",NULL,NULL,NULL);
        if (rc != SQLITE_OK) {
                puts(sqlite3_errmsg(db));
        }
 rc=sqlite3_exec(db,"create table t2 (n integer)",NULL,NULL,NULL);
        if (rc != SQLITE_OK) {
                puts(sqlite3_errmsg(db));
        }
 rc=sqlite3_exec(db,"insert into t2 values(0)",NULL,NULL,NULL);
        if (rc != SQLITE_OK) {
                puts(sqlite3_errmsg(db));
        }
 if (flags & 16) {
  rc=sqlite3_exec(db,"pragma synchronous=OFF",NULL,NULL,NULL);
         if (rc != SQLITE_OK) {
                 puts(sqlite3_errmsg(db));
         }
 }
 if (flags & 2) {
  rc=sqlite3_exec(db,"create index tx on t (i)",NULL,NULL,NULL);
         if (rc != SQLITE_OK) {
                 puts(sqlite3_errmsg(db));
         }
 }
 if (flags & 4) {
  rc=sqlite3_exec(db,"pragma journal_mode=WAL",NULL,NULL,NULL);
         if (rc != SQLITE_OK) {
                 puts(sqlite3_errmsg(db));
         }
 }
 if (flags & 8) {
  AddTrigger(db);
  if (interval != 1) {
   fprintf(stderr,"Can't do trigger and begin/commit together\n");
   exit(-1);
  }
 }
 sqlite3_prepare_v2(db,"insert into t values(?)",-1,&stmt,NULL);
 t1=elapsed();
 if (interval != 1) rc=sqlite3_exec(db,"begin",NULL,NULL,NULL);
 while(n < nrec) {
  ++n;
  if (interval != 1 && (n% interval)==0) {
   sqlite3_exec(db,"commit",NULL,NULL,NULL);
   sqlite3_exec(db,"begin",NULL,NULL,NULL);
  }
  sqlite3_bind_int(stmt,1,n);
  rc = sqlite3_step(stmt);
  if (rc != SQLITE_DONE) {
   puts(sqlite3_errmsg(db));
  }
  sqlite3_reset(stmt);
 }
 sqlite3_exec(db,"commit",NULL,NULL,NULL);
 printf("%.1f\n",nrec/(elapsed()-t1));
 sqlite3_close(db);
}
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to