Re: [sqlite] Single row insert speeds

2007-12-04 Thread drh
"Mark Riehl" <[EMAIL PROTECTED]> wrote:
>> 
> For testing, I've modified the the insert to look like this:
> char *insertStatement = "PRAGMA synchronous=OFF;BEGIN;INSERT INTO
> sampleTable VALUES (\"hostname\", \"6\", \"5.1.0\", \"0\", \"1708\",
> \"1196303669.065335988998\",
> \"hostIfc=eth0:1;hostIp=172.16.1.1;msgCount=0;queueSize=0 (0
> peak);\");COMMIT;";
> 
> Is this the correct syntax for the PRAGMA statement?  Can I issue it
> once and will it remain active as long as the connection is open?
> 

The PRAGMA syntax is correct.  Issue it once when you initially
open the connection.  The BEGIN and COMMIT are automatic and
can be omitted (for additional speed).  SQL wants values to
be quoted using single-quotes, not double-quotes.  SQLite allows
double-quotes but it is technically wrong.
--
D. Richard Hipp <[EMAIL PROTECTED]>


-
To unsubscribe, send email to [EMAIL PROTECTED]
-



Re: [sqlite] Single row insert speeds

2007-12-04 Thread Mark Riehl
All - After reviewing some of my calculations, I realized I made a
mistake and that the inserts didn't improve as much as I thought.  I
used the PRAGMA synchronouse = OFF and I'm averaging about 0.21 ms for
an insert on a Core 2 Shuttle running Fedora 3.

Here is the table I've defined:
CREATE TABLE sampleTable (
 logHost varchar(64) DEFAULT NULL,
 compId smallint(5) DEFAULT NULL,
 pid int(10) DEFAULT NULL,
 version varchar(8) DEFAULT NULL,
 rptTime decimal(20,6) DEFAULT NULL,
 rptStatus tinyint(3) DEFAULT NULL,
 data text
);

Here is a typical insert:

INSERT INTO sampleTable
VALUES (\"hostname\", \"6\", \"5.1.0\", \"0\", \"1708\", \"1196303669.06533598
8998\", \"hostIfc=eth0:1;hostIp=172.16.1.1;msgCount=0;queueSize=0 (0 peak)
;\")";

For testing, I've modified the the insert to look like this:
char *insertStatement = "PRAGMA synchronous=OFF;BEGIN;INSERT INTO
sampleTable VALUES (\"hostname\", \"6\", \"5.1.0\", \"0\", \"1708\",
\"1196303669.065335988998\",
\"hostIfc=eth0:1;hostIp=172.16.1.1;msgCount=0;queueSize=0 (0
peak);\");COMMIT;";

Is this the correct syntax for the PRAGMA statement?  Can I issue it
once and will it remain active as long as the connection is open?

Thanks,
Mark


On Dec 3, 2007 6:45 PM, Mark Riehl <[EMAIL PROTECTED]> wrote:
> I used the PRAGMA statement and turned off the synchronous option.  It
> made a huge difference.  Single inserts were ranging from 5 - 50 ms,
> now, they're at ~.04 ms.
>
> However, I guess there is a tradeoff between the safety of the
> synchronous operation (in case power is lost) versus the insert
> speeds.
>
> Thanks for the help,
> Mark
>
>
> On Dec 3, 2007 12:59 PM,  <[EMAIL PROTECTED]> wrote:
> > "P Kishor" <[EMAIL PROTECTED]> wrote:
> > > I get 1000+ inserts a second for a random 100 byte string
> > > insert (
> >
> > I get 5+ inserts/sec on my Linux box.
> >
> > Insert speed is not the issue.  It is COMMIT speed.  At
> > each commit, SQLite waits until all data is on oxide before
> > continuing.  That will typically take at least two rotations
> > of the disk platter, or about 17 millisecond, depending on
> > your disk drive.  Waiting for data to get to oxide is
> > part of being ACID.  You can set:
> >
> >PRAGMA synchronous=OFF;
> >
> > and your COMMITs will go *much* faster because it will no
> > longer wait on the disk drive.  But if you lose
> > power in the middle of a commit, you might corrupt your
> > database file.
> >
> > Note that there is an implied BEGIN...COMMIT around every
> > INSERT statement if you do not explicitly start a transaction
> > using your own BEGIN.
> >
> > --
> > D. Richard Hipp <[EMAIL PROTECTED]>
> >
> >
> >
> > -
> > To unsubscribe, send email to [EMAIL PROTECTED]
> > -
> >
> >
>

-
To unsubscribe, send email to [EMAIL PROTECTED]
-



Re: [sqlite] Single row insert speeds

2007-12-03 Thread Ken
I have a few suggestions for you to try: 
 1. Use prepared statements. Do not free the statement, reset it and re-use 
that way you don't incure the parsing overhead for each statement.
 2. Use bind variables in conjunction.
   
  Redesign to perform more than single row inserts into a transaction. Perhaps 
utilizing a timer or data row count to trigger a commit.
   
 

Mark Riehl <[EMAIL PROTECTED]> wrote:
  I've got an application that logs real-time data. Some of the data is
periodic (every few secs), other data comes more frequently.
Basically, I'm not dealing with bulk inserts, so, I can't queue things
up and insert all at once.

I'm noticing that my insert times are pretty slow (~5-50 ms on a Intel
Core 2) for a single record of ~100 bytes.

Any suggestions for speeding up single row inserts? I saw some of the
other threads on using transactions, but, not sure if that applied to
single inserts.

Here is a simple app I wrote to test the timing:

int rc = sqlite3_open("mydb.db", &db);

for (i = 0; i < 10; i++) {

printf("Executing %s\n", insertStatement);

gettimeofday(&before, 0);
rc = sqlite3_exec(db, insertStatement, NULL, NULL, &zErr);
gettimeofday(&after, 0);
if (rc != SQLITE_OK) {
...
}
}

printf("Before %d %d\n", before.tv_sec, before.tv_usec);
printf("After %d %d\n", after.tv_sec, after.tv_usec);

sleep(1);
}

sqlite3_close(db);

Thanks for the help,
Mark

-
To unsubscribe, send email to [EMAIL PROTECTED]
-




Re: [sqlite] Single row insert speeds

2007-12-03 Thread John Stanton
A faster disk will give you better performance.  A 15,000 rpm disk will 
give almost three times the performance of a 5,400 rpm one and retain 
the ACID mode.


You could also queue your input and launch periodic Sqlite transactions 
to empty the queue.


Mike Marshall wrote:

What platform are you running on?

Most of these sorts of issues that have come up before relate to the fact
that SQLite is committing the data to the disc with each insert and has to
ensure that the buffer has been written before it can process the next
insert.

IIRC there is a PRAGMA to switch this behavior off, but of course you then
lose your ACID compliance which may or may not be a big deal to you.

This page http://www.sqlite.org/cvstrac/wiki?p=SpeedComparison might also be
useful to you.

M

-Original Message-
From: Mark Riehl [mailto:[EMAIL PROTECTED] 
Sent: 03 December 2007 16:58

To: sqlite-users@sqlite.org
Subject: [sqlite] Single row insert speeds

I've got an application that logs real-time data.  Some of the data is
periodic (every few secs), other data comes more frequently.
Basically, I'm not dealing with bulk inserts, so, I can't queue things
up and insert all at once.

I'm noticing that my insert times are pretty slow (~5-50 ms on a Intel
Core 2) for a single record of ~100 bytes.

Any suggestions for speeding up single row inserts?  I saw some of the
other threads on using transactions, but, not sure if that applied to
single inserts.

Here is a simple app I wrote to test the timing:

   int rc = sqlite3_open("mydb.db", &db);

for (i = 0; i < 10; i++) {

  printf("Executing %s\n", insertStatement);

  gettimeofday(&before, 0);
  rc = sqlite3_exec(db, insertStatement, NULL, NULL, &zErr);
  gettimeofday(&after, 0);
  if (rc != SQLITE_OK) {
 ...
}
  }

  printf("Before %d %d\n", before.tv_sec, before.tv_usec);
  printf("After %d %d\n", after.tv_sec, after.tv_usec);

  sleep(1);
}

sqlite3_close(db);

Thanks for the help,
Mark


-
To unsubscribe, send email to [EMAIL PROTECTED]

-



-
To unsubscribe, send email to [EMAIL PROTECTED]
-




-
To unsubscribe, send email to [EMAIL PROTECTED]
-



Re: [sqlite] Single row insert speeds

2007-12-03 Thread P Kishor
On 12/3/07, Mark Riehl <[EMAIL PROTECTED]> wrote:
> I used the PRAGMA statement and turned off the synchronous option.  It
> made a huge difference.  Single inserts were ranging from 5 - 50 ms,
> now, they're at ~.04 ms.
>
> However, I guess there is a tradeoff between the safety of the
> synchronous operation (in case power is lost) versus the insert
> speeds.

there is always a tradeoff between caution and impetuousness. Such is life.

Glad it worked out for you.

;-)




>
> Thanks for the help,
> Mark
>
> On Dec 3, 2007 12:59 PM,  <[EMAIL PROTECTED]> wrote:
> > "P Kishor" <[EMAIL PROTECTED]> wrote:
> > > I get 1000+ inserts a second for a random 100 byte string
> > > insert (
> >
> > I get 5+ inserts/sec on my Linux box.
> >
> > Insert speed is not the issue.  It is COMMIT speed.  At
> > each commit, SQLite waits until all data is on oxide before
> > continuing.  That will typically take at least two rotations
> > of the disk platter, or about 17 millisecond, depending on
> > your disk drive.  Waiting for data to get to oxide is
> > part of being ACID.  You can set:
> >
> >PRAGMA synchronous=OFF;
> >
> > and your COMMITs will go *much* faster because it will no
> > longer wait on the disk drive.  But if you lose
> > power in the middle of a commit, you might corrupt your
> > database file.
> >
> > Note that there is an implied BEGIN...COMMIT around every
> > INSERT statement if you do not explicitly start a transaction
> > using your own BEGIN.
> >
> > --
> > D. Richard Hipp <[EMAIL PROTECTED]>
> >
> >

-
To unsubscribe, send email to [EMAIL PROTECTED]
-



Re: [sqlite] Single row insert speeds

2007-12-03 Thread Mark Riehl
I used the PRAGMA statement and turned off the synchronous option.  It
made a huge difference.  Single inserts were ranging from 5 - 50 ms,
now, they're at ~.04 ms.

However, I guess there is a tradeoff between the safety of the
synchronous operation (in case power is lost) versus the insert
speeds.

Thanks for the help,
Mark

On Dec 3, 2007 12:59 PM,  <[EMAIL PROTECTED]> wrote:
> "P Kishor" <[EMAIL PROTECTED]> wrote:
> > I get 1000+ inserts a second for a random 100 byte string
> > insert (
>
> I get 5+ inserts/sec on my Linux box.
>
> Insert speed is not the issue.  It is COMMIT speed.  At
> each commit, SQLite waits until all data is on oxide before
> continuing.  That will typically take at least two rotations
> of the disk platter, or about 17 millisecond, depending on
> your disk drive.  Waiting for data to get to oxide is
> part of being ACID.  You can set:
>
>PRAGMA synchronous=OFF;
>
> and your COMMITs will go *much* faster because it will no
> longer wait on the disk drive.  But if you lose
> power in the middle of a commit, you might corrupt your
> database file.
>
> Note that there is an implied BEGIN...COMMIT around every
> INSERT statement if you do not explicitly start a transaction
> using your own BEGIN.
>
> --
> D. Richard Hipp <[EMAIL PROTECTED]>
>
>
>
> -
> To unsubscribe, send email to [EMAIL PROTECTED]
> -
>
>

-
To unsubscribe, send email to [EMAIL PROTECTED]
-



Re: [sqlite] Single row insert speeds

2007-12-03 Thread P Kishor
On 12/3/07, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
> "P Kishor" <[EMAIL PROTECTED]> wrote:
> > I get 1000+ inserts a second for a random 100 byte string
> > insert (
>
> I get 5+ inserts/sec on my Linux box.

turned off AutoCommit, turned off rand string generation, and lookee
what I get...

200,000 inserts in half a second. If my math is not wrong, that works
out to more than 360 thousand inserts per sec on the same laptop with
a 5400 rpm 2.5" disk. Of course, I batched up the commit at the end.
Including the COMMIT, the speed dropped down to almost 67,000 inserts
per sec.

sqlite> select count(*) from foo;
21
sqlite>


All of the below comes from a wiser man than I.

>
> Insert speed is not the issue.  It is COMMIT speed.  At
> each commit, SQLite waits until all data is on oxide before
> continuing.  That will typically take at least two rotations
> of the disk platter, or about 17 millisecond, depending on
> your disk drive.  Waiting for data to get to oxide is
> part of being ACID.  You can set:
>
>PRAGMA synchronous=OFF;
>
> and your COMMITs will go *much* faster because it will no
> longer wait on the disk drive.  But if you lose
> power in the middle of a commit, you might corrupt your
> database file.
>
> Note that there is an implied BEGIN...COMMIT around every
> INSERT statement if you do not explicitly start a transaction
> using your own BEGIN.
>
> --
> D. Richard Hipp <[EMAIL PROTECTED]>
>

-
To unsubscribe, send email to [EMAIL PROTECTED]
-



Re: [sqlite] Single row insert speeds

2007-12-03 Thread drh
"P Kishor" <[EMAIL PROTECTED]> wrote:
> I get 1000+ inserts a second for a random 100 byte string
> insert (

I get 5+ inserts/sec on my Linux box.

Insert speed is not the issue.  It is COMMIT speed.  At
each commit, SQLite waits until all data is on oxide before
continuing.  That will typically take at least two rotations
of the disk platter, or about 17 millisecond, depending on
your disk drive.  Waiting for data to get to oxide is
part of being ACID.  You can set:

   PRAGMA synchronous=OFF;

and your COMMITs will go *much* faster because it will no
longer wait on the disk drive.  But if you lose
power in the middle of a commit, you might corrupt your
database file.

Note that there is an implied BEGIN...COMMIT around every
INSERT statement if you do not explicitly start a transaction
using your own BEGIN.

--
D. Richard Hipp <[EMAIL PROTECTED]>


-
To unsubscribe, send email to [EMAIL PROTECTED]
-



Re: [sqlite] Single row insert speeds

2007-12-03 Thread Mark Riehl
I'm running SQLite 3.1.13 under Fedora 3.  Our real app is written in
C++.  The sample I wrote to debug the insert times is written in C
(gcc 3.4.2).

Here is the table I've defined:
CREATE TABLE sampleTable (
  logHost varchar(64) DEFAULT NULL,
  compId smallint(5) DEFAULT NULL,
  pid int(10) DEFAULT NULL,
  version varchar(8) DEFAULT NULL,
  rptTime decimal(20,6) DEFAULT NULL,
  rptStatus tinyint(3) DEFAULT NULL,
  data text
);

And I have an index on the compId column.

Here is a typical insert:

INSERT INTO sampleTable
VALUES (\"hostname\", \"6\", \"5.1.0\", \"0\", \"1708\", \"1196303669.06533598
8998\", \"hostIfc=eth0:1;hostIp=172.16.1.1;msgCount=0;queueSize=0 (0 peak)
;\")";

As I said, this is taking anywhere from 5-50 ms.

Running 10 times in a loop (with a 1 sec sleep in between to let it
finish), here is what I see for insert times:

Insert time in ms 57.444000
Insert time in ms 6.031000
Insert time in ms 5.048000
Insert time in ms 6.372000
Insert time in ms 4.786000
Insert time in ms 11.169000
Insert time in ms 4.02
Insert time in ms 5.211000
Insert time in ms 7.112000
Insert time in ms 3.962000

Thanks,
Mark


On Dec 3, 2007 12:30 PM, P Kishor <[EMAIL PROTECTED]> wrote:
> you would need to give more info about your db, the data, etc. On my
> Macbook Pro, I get 1000+ inserts a second for a random 100 byte string
> insert (that is, less than one per ms). That includes the time to
> generate the string, and is all in Perl, while I am listening to
> iTunes, and no funny pragma trix. Code follows...
>
> I am using SQLite 3.4.2
>
> CREATE TABLE foo (a);
>
> sub speedtest {
>   $sth->execute( str() )
> }
>
> sub str {
>   my $str;
>   for (0 .. 99) {
> $str .= ('a' .. 'z')[int(rand(25)) + 1];
>   }
>   return $str;
> }
>
> timethis(1000, \&speed);
>
> $ ./db.pl
> timethis 1000:  2 wallclock secs ( 0.20 usr +  0.75 sys =  0.95 CPU) @
> 1052.63/s (n=1000)
>
>
> On 12/3/07, Mark Riehl <[EMAIL PROTECTED]> wrote:
> > I've got an application that logs real-time data.  Some of the data is
> > periodic (every few secs), other data comes more frequently.
> > Basically, I'm not dealing with bulk inserts, so, I can't queue things
> > up and insert all at once.
> >
> > I'm noticing that my insert times are pretty slow (~5-50 ms on a Intel
> > Core 2) for a single record of ~100 bytes.
> >
> > Any suggestions for speeding up single row inserts?  I saw some of the
> > other threads on using transactions, but, not sure if that applied to
> > single inserts.
> >
> > Here is a simple app I wrote to test the timing:
> >
> >int rc = sqlite3_open("mydb.db", &db);
> >
> > for (i = 0; i < 10; i++) {
> >
> >   printf("Executing %s\n", insertStatement);
> >
> >   gettimeofday(&before, 0);
> >   rc = sqlite3_exec(db, insertStatement, NULL, NULL, &zErr);
> >   gettimeofday(&after, 0);
> >   if (rc != SQLITE_OK) {
> >  ...
> > }
> >   }
> >
> >   printf("Before %d %d\n", before.tv_sec, before.tv_usec);
> >   printf("After %d %d\n", after.tv_sec, after.tv_usec);
> >
> >   sleep(1);
> > }
> >
> > sqlite3_close(db);
> >
> > Thanks for the help,
> > Mark
> >
> > -
> > To unsubscribe, send email to [EMAIL PROTECTED]
> > -
> >
> >
>
>
> --
> Puneet Kishor
> http://punkish.eidesis.org/
> Nelson Institute for Environmental Studies
> http://www.nelson.wisc.edu/
> Open Source Geospatial Foundation (OSGeo)
> http://www.osgeo.org/
> Summer 2007 S&T Policy Fellow, The National Academies
> http://www.nas.edu/
>
> -
>
> To unsubscribe, send email to [EMAIL PROTECTED]
> -
>
>

-
To unsubscribe, send email to [EMAIL PROTECTED]
-



Re: [sqlite] Single row insert speeds

2007-12-03 Thread Günter Greschenz

hi,

i am using a "commit-thread":
my application is starting a transaction with "begin" and is inserting a 
lot of data at random times,
a thread is doing "commit" and "begin" every second (while locking the 
main app of course :-).

this runs very fast and in case of crashes i loose only 1 second of data !

cu, gg



Mark Riehl wrote:

I've got an application that logs real-time data.  Some of the data is
periodic (every few secs), other data comes more frequently.
Basically, I'm not dealing with bulk inserts, so, I can't queue things
up and insert all at once.

I'm noticing that my insert times are pretty slow (~5-50 ms on a Intel
Core 2) for a single record of ~100 bytes.

Any suggestions for speeding up single row inserts?  I saw some of the
other threads on using transactions, but, not sure if that applied to
single inserts.

Here is a simple app I wrote to test the timing:

   int rc = sqlite3_open("mydb.db", &db);

for (i = 0; i < 10; i++) {

  printf("Executing %s\n", insertStatement);

  gettimeofday(&before, 0);
  rc = sqlite3_exec(db, insertStatement, NULL, NULL, &zErr);
  gettimeofday(&after, 0);
  if (rc != SQLITE_OK) {
 ...
}
  }

  printf("Before %d %d\n", before.tv_sec, before.tv_usec);
  printf("After %d %d\n", after.tv_sec, after.tv_usec);

  sleep(1);
}

sqlite3_close(db);

Thanks for the help,
Mark

-
To unsubscribe, send email to [EMAIL PROTECTED]
-


  



-
To unsubscribe, send email to [EMAIL PROTECTED]
-



Re: [sqlite] Single row insert speeds

2007-12-03 Thread P Kishor
you would need to give more info about your db, the data, etc. On my
Macbook Pro, I get 1000+ inserts a second for a random 100 byte string
insert (that is, less than one per ms). That includes the time to
generate the string, and is all in Perl, while I am listening to
iTunes, and no funny pragma trix. Code follows...

I am using SQLite 3.4.2

CREATE TABLE foo (a);

sub speedtest {
  $sth->execute( str() )
}

sub str {
  my $str;
  for (0 .. 99) {
$str .= ('a' .. 'z')[int(rand(25)) + 1];
  }
  return $str;
}

timethis(1000, \&speed);

$ ./db.pl
timethis 1000:  2 wallclock secs ( 0.20 usr +  0.75 sys =  0.95 CPU) @
1052.63/s (n=1000)

On 12/3/07, Mark Riehl <[EMAIL PROTECTED]> wrote:
> I've got an application that logs real-time data.  Some of the data is
> periodic (every few secs), other data comes more frequently.
> Basically, I'm not dealing with bulk inserts, so, I can't queue things
> up and insert all at once.
>
> I'm noticing that my insert times are pretty slow (~5-50 ms on a Intel
> Core 2) for a single record of ~100 bytes.
>
> Any suggestions for speeding up single row inserts?  I saw some of the
> other threads on using transactions, but, not sure if that applied to
> single inserts.
>
> Here is a simple app I wrote to test the timing:
>
>int rc = sqlite3_open("mydb.db", &db);
>
> for (i = 0; i < 10; i++) {
>
>   printf("Executing %s\n", insertStatement);
>
>   gettimeofday(&before, 0);
>   rc = sqlite3_exec(db, insertStatement, NULL, NULL, &zErr);
>   gettimeofday(&after, 0);
>   if (rc != SQLITE_OK) {
>  ...
> }
>   }
>
>   printf("Before %d %d\n", before.tv_sec, before.tv_usec);
>   printf("After %d %d\n", after.tv_sec, after.tv_usec);
>
>   sleep(1);
> }
>
> sqlite3_close(db);
>
> Thanks for the help,
> Mark
>
> -
> To unsubscribe, send email to [EMAIL PROTECTED]
> -
>
>


-- 
Puneet Kishor
http://punkish.eidesis.org/
Nelson Institute for Environmental Studies
http://www.nelson.wisc.edu/
Open Source Geospatial Foundation (OSGeo)
http://www.osgeo.org/
Summer 2007 S&T Policy Fellow, The National Academies
http://www.nas.edu/

-
To unsubscribe, send email to [EMAIL PROTECTED]
-



RE: [sqlite] Single row insert speeds

2007-12-03 Thread Mike Marshall
What platform are you running on?

Most of these sorts of issues that have come up before relate to the fact
that SQLite is committing the data to the disc with each insert and has to
ensure that the buffer has been written before it can process the next
insert.

IIRC there is a PRAGMA to switch this behavior off, but of course you then
lose your ACID compliance which may or may not be a big deal to you.

This page http://www.sqlite.org/cvstrac/wiki?p=SpeedComparison might also be
useful to you.

M

-Original Message-
From: Mark Riehl [mailto:[EMAIL PROTECTED] 
Sent: 03 December 2007 16:58
To: sqlite-users@sqlite.org
Subject: [sqlite] Single row insert speeds

I've got an application that logs real-time data.  Some of the data is
periodic (every few secs), other data comes more frequently.
Basically, I'm not dealing with bulk inserts, so, I can't queue things
up and insert all at once.

I'm noticing that my insert times are pretty slow (~5-50 ms on a Intel
Core 2) for a single record of ~100 bytes.

Any suggestions for speeding up single row inserts?  I saw some of the
other threads on using transactions, but, not sure if that applied to
single inserts.

Here is a simple app I wrote to test the timing:

   int rc = sqlite3_open("mydb.db", &db);

for (i = 0; i < 10; i++) {

  printf("Executing %s\n", insertStatement);

  gettimeofday(&before, 0);
  rc = sqlite3_exec(db, insertStatement, NULL, NULL, &zErr);
  gettimeofday(&after, 0);
  if (rc != SQLITE_OK) {
 ...
}
  }

  printf("Before %d %d\n", before.tv_sec, before.tv_usec);
  printf("After %d %d\n", after.tv_sec, after.tv_usec);

  sleep(1);
}

sqlite3_close(db);

Thanks for the help,
Mark


-
To unsubscribe, send email to [EMAIL PROTECTED]

-



-
To unsubscribe, send email to [EMAIL PROTECTED]
-