> I fixed a couple of bugs in my program...I had converted from clock() to
> the more appropriate gettimeofday and forgot to remove the CLOCKS_PER_SEC
> factor (what's a few order of magnitude between friends :-).  Plus I added
> a 3rd argument so you can in-memory, index, and WAL mode too (or combine
> them).
>
> I should've realized it wasn't running this fast but the small 5000 record
> size got me.
> Test it yourself.
> I do have a 7200RPM drive.  My 261.4 numer is still 2+X your theoretical.

I don't want to be a smart-arse, but I still think your 261.4 is to fast.
On a 7200 RPM drive one will have 125 chances/sec to see a sector to be
written. Since sqlite, under normal journal mode, will need 3 syncs
per commit as far as I can recall, the maximum number drops further
down to 41 commit/sec. This is theoretical, in reality one will see
maybe 20 commits/sec. Not sure if a disc write-cache will interfere
with that caluclation, though.
Am I wrong ? :-)

Your loop omits the sqlite_reset call between the bind statements:
This is allowed since some sqlite versions but I'm not sure if
you are really resetting the implicit transaction. Just an idea..

Your new code still uses the clocks scaling:
printf("%.1f\n",nrec/((elapsed()-t1)/CLOCKS_PER_SEC));
That looks strange to me as your are probably scaling seconds
down to milliseconds, or something.

Marcus


>
> batch 5000000 5000000 0
> 274207.4
> batch 5000000 5000000 1 -- memory
> 540540.5
> batch 5000000 5000000 2 -- w/index
> 160481.4
> batch 5000000 5000000 3 -- memory+index
> 220689.7
> batch 5000000 5000000 4 -- WAL mode
> 441989.0
> batch 5000000 5000000 5 -- WAL mode+memory
> 541455.2
> batch 5000000 5000000 6 -- WAL mode+index
> 188902.0
> batch 5000000 5000000 7 -- WAL mode+index+memory
> 219478.7
>
> And doing the 5000 record example and testing commit intervals
> batch 5000 5000 0
> 320000.0
> batch 5000 2500 0
> 320000.0
> batch 5000 1200 0
> 160000.0
> batch 5000 500 0
> 160000.0
> batch 5000 200 0
> 80000.0
> batch 5000 100 0
> 35555.6
> batch 5000 500 0
> 160000.0
> batch 5000 50 0
> 20000.0
> batch 5000 25 0
> 11034.5
> batch 5000 12 0
> 5333.3
> batch 5000 6 0
> 2461.5
> batch 5000 3 0
> 682.3
> batch 5000 2 0
> 509.6
> batch 5000 1 0
> 261.4
>
> #include <stdio.h>
> #include <windows.h>
> #include <winbase.h>
> #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 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,"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));
>  }
>  sqlite3_exec(db,"create table t (i integer)",NULL,NULL,NULL);
>  if (flags & 2) {
>   sqlite3_exec(db,"create index tx on t (i)",NULL,NULL,NULL);
>  }
>  if (flags & 4) {
>   sqlite3_exec(db,"pragma journal_mode=WAL",NULL,NULL,NULL);
>  }
>  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 inserts per sec\n",nrec/((elapsed()-t1)/CLOCKS_PER_SEC));
>  printf("%.1f\n",nrec/((elapsed()-t1)/CLOCKS_PER_SEC));
>  sqlite3_close(db);
> }
>
>
>
> Michael D. Black
> Senior Scientist
> NG Information Systems
> Advanced Analytics Directorate
>
>
>
> ________________________________________
> From: sqlite-users-boun...@sqlite.org [sqlite-users-boun...@sqlite.org] on
> behalf of Jim Wilcoxson [pri...@gmail.com]
> Sent: Saturday, February 12, 2011 10:11 AM
> To: General Discussion of SQLite Database
> Subject: EXT :Re: [sqlite] UPDATE/INSERTing 1-2k rows slower than expected
>
> On Sat, Feb 12, 2011 at 9:10 AM, Black, Michael (IS)
> <michael.bla...@ngc.com
>> wrote:
>
>> Here's a little benchmark program I wrote to test a super-simple
>> one-integer insert to test sql speed and commit interval behavior.
>>
>> Running it on my machine (Windows XP64 8-core 3Ghz gcc (tdm64-1) 4.5.1)
>> I
>> go from 320M inserts per second to 361K inserts per second when no
>> begin/commit occurs.  With WAL mode turned on it only drops to 5.9M
>> inserts
>> per second.
>>
>> D:\SQLite>batch 5000 5000
>> 320000000.0 inserts per sec
>> D:\SQLite>batch 5000 2500
>> 320000000.0 inserts per sec
>> D:\SQLite>batch 5000 1200
>> 160000000.0 inserts per sec
>> D:\SQLite>batch 5000 600
>> 160000000.0 inserts per sec
>> D:\SQLite>batch 5000 300
>> 106666666.7 inserts per sec
>> D:\SQLite>batch 5000 150
>> 53333333.3 inserts per sec
>> D:\SQLite>batch 5000 75
>> 32000000.0 inserts per sec
>> D:\SQLite>batch 5000 40
>> 17777777.8 inserts per sec
>> D:\SQLite>batch 5000 20
>> 10000000.0 inserts per sec
>> D:\SQLite>batch 5000 10
>> 3333333.3 inserts per sec
>> D:\SQLite>batch 5000 5
>> 2406015.0 inserts per sec
>> D:\SQLite>batch 5000 2
>> 526315.8 inserts per sec
>> D:\SQLite>batch 5000 1
>> 360766.6 inserts per sec
>>
>
> Unless I'm missing something, SQLite has to update the first page of the
> database on every commit, to update the change counter.  Assuming you are
> using rotating media, that record can only be updated 120 times per
> second,
> maximum, on a 7200RPM drive.
>
> I don't understand how you can do 360K commits per second if your system
> is
> actually doing "to the platter" writes on every commit.  Can someone clue
> me
> in?
>
> Jim
> --
> HashBackup: easy onsite and offsite Unix backup
> http://www.hashbackup.com
> _______________________________________________
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
> _______________________________________________
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>


_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to