Re: [sqlite] WAL and updates

2012-11-28 Thread Richard Hipp
On Tue, Nov 27, 2012 at 11:16 PM, Keith Chew  wrote:

> I have found that after performing 5000 single transaction inserts, the WAL
> size grows to approx 90MB. After a checkpoint, it becomes 0 and the main
> DB's size goes up by less than 2MB. Is my observation correct? Ie am I
> expecting such a huge size difference between the WAL and main DB file
> formats?
>

In WAL mode, SQLite appends deltas of the database changes to the WAL
file.  Each transaction commits as its delta is appended.  The checkpoint
operation transfers these deltas into the main database file.  Prior to a
checkpoint, the main database file is unchanged in WAL mode.  In WAL mode,
a checkpoint is the only operation that ever changes the main database.

If you do 5000 transactions without a checkpoint, and the delta for each
transaction is 4 or 5 pages of 4KB each, that would come to about 90MB.
You might want to consider doing checkpoints more frequently to prevent the
WAL file from growing so large.


-- 
D. Richard Hipp
d...@sqlite.org
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] WAL and updates

2012-11-27 Thread Keith Chew
> Thanks for this Simon, but unfortunately this is legacy code, which has to
> be used for a while. I just did an update to check for column change (we
> have a column to tell us the record has changed, so we do not need to check
> every column), and the WAL file size growth has dropped significantly. So,
> will keep working at it.
>
>
I have found that after performing 5000 single transaction inserts, the WAL
size grows to approx 90MB. After a checkpoint, it becomes 0 and the main
DB's size goes up by less than 2MB. Is my observation correct? Ie am I
expecting such a huge size difference between the WAL and main DB file
formats?

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


Re: [sqlite] WAL and updates

2012-11-25 Thread Keith Chew
>
>
>
> Okay, if you're doing this set up updates to do synchronisation then
> you're going about it a very poor way.  We've written a lot on this list
> about the problems with synchronisation over the years and you'll find that
> your way isn't going to be efficient.
>
> Instead of keeping a list of the modified data, consider keeping a list of
> the commands used to modify it. Or logging the fields modified as they're
> modified.
>
>
Thanks for this Simon, but unfortunately this is legacy code, which has to
be used for a while. I just did an update to check for column change (we
have a column to tell us the record has changed, so we do not need to check
every column), and the WAL file size growth has dropped significantly. So,
will keep working at it.

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


Re: [sqlite] WAL and updates

2012-11-25 Thread Simon Slavin

On 25 Nov 2012, at 9:12pm, Keith Chew  wrote:

> Ok, thanks for the all the suggestions, I will find a workaround. The
> reason I am asking is that I am using sqlite to perform data
> synchronisation between a server and client, and after a day, the WAL file
> size can grow to 3GB, quite a bit. I will look at improving the SQL update
> to reduce some of the overhead.

Okay, if you're doing this set up updates to do synchronisation then you're 
going about it a very poor way.  We've written a lot on this list about the 
problems with synchronisation over the years and you'll find that your way 
isn't going to be efficient.

Instead of keeping a list of the modified data, consider keeping a list of the 
commands used to modify it. Or logging the fields modified as they're modified.

Simon.

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


Re: [sqlite] WAL and updates

2012-11-25 Thread Richard Hipp
On Sun, Nov 25, 2012 at 4:12 PM, Keith Chew  wrote:

> Hi
>
> Ok, thanks for the all the suggestions, I will find a workaround. The
> reason I am asking is that I am using sqlite to perform data
> synchronisation between a server and client, and after a day, the WAL file
> size can grow to 3GB, quite a bit.


Performance can get really bad when you let the WAL file grow that large.
You should probably try to keep the WAL file size to a maximum of a few
megabytes.



> I will look at improving the SQL update
> to reduce some of the overhead.
>
> I have also found that when a record is inserted 4K is added to the WAL,
> and when the record is deleted, another 3K is added. This
> (insertion/deletion) happens quite a lot during data synchronisation, and
> it seems to be an expensive thing (7K) in terms of WAL size growth
>



>
> Regards
> Keith
> ___
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>



-- 
D. Richard Hipp
d...@sqlite.org
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] WAL and updates

2012-11-25 Thread Keith Chew
Hi

Ok, thanks for the all the suggestions, I will find a workaround. The
reason I am asking is that I am using sqlite to perform data
synchronisation between a server and client, and after a day, the WAL file
size can grow to 3GB, quite a bit. I will look at improving the SQL update
to reduce some of the overhead.

I have also found that when a record is inserted 4K is added to the WAL,
and when the record is deleted, another 3K is added. This
(insertion/deletion) happens quite a lot during data synchronisation, and
it seems to be an expensive thing (7K) in terms of WAL size growth

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


Re: [sqlite] WAL and updates

2012-11-25 Thread Simon Slavin

On 25 Nov 2012, at 4:22pm, Imanuel  wrote:

> I'm not saying your statement is inefficient, I'm saying it's wrong
> because it produces unwanted results.
> 
> If the fields a,b,c ('12','34','56') should be updated to
> ('1','2345','6') your statement would fail instead of doing the expected
> update.

You're absolutely right.  I should be worried about false negatives.  It's the 
false positives I don't have to worry about.  Thanks for the correction.

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


Re: [sqlite] WAL and updates

2012-11-25 Thread Imanuel
That's better, but only if you know for sure that the data doesn't
contain '-'.

Otherwise, you run into the same problem with the following values:
'1-','2','3' -> '1','-2','3'

Imanuel



Am 25.11.2012 17:35, schrieb Roger Andersson:
> Then something like
> WHERE a||'-'||b||'-'||c||'-' != ...
> 
> Maybe there are other drawbacks?
> 
> //Roger
> -Ursprungligt meddelande- From: Imanuel Sent: Sunday, November
> 25, 2012 5:22 PM To: sqlite-users@sqlite.org Subject: Re: [sqlite] WAL
> and updates
> I'm not saying your statement is inefficient, I'm saying it's wrong
> because it produces unwanted results.
> 
> If the fields a,b,c ('12','34','56') should be updated to
> ('1','2345','6') your statement would fail instead of doing the expected
> update.
> 
> Which means with every false hit it has less data to write and thus is
> faster because of the false hits (instead of "even with").
> 
> Imanuel
> 
> 
> 
> Am 25.11.2012 17:13, schrieb Simon Slavin:
>>
>> On 25 Nov 2012, at 4:11pm, Imanuel  wrote:
>>
>>> Hi Keith
>>>
>>>> UPDATE user SET a=1,b=2,c=3 WHERE a||b||c!=1||2||3;
>>>
>>> It seems to me that this is not reliable.
>>> Think the the following text values:
>>> a='12'
>>> b='34'
>>> c='56'
>>>
>>> If you want to update these values to:
>>> a='1'
>>> b='2345'
>>> c='6'
>>>
>>> Then your statement would not update because '123456' = '123456'.
>>
>> You're quite right, but in some cases it's sufficiently faster than doing
>>
>> WHERE a!=1 OR b!=2 OR c!=3
>>
>> that even with the false hits it takes less time to process.
>>
>> Simon.
>> ___
>> 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
> 
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] WAL and updates

2012-11-25 Thread Roger Andersson

Then something like
WHERE a||'-'||b||'-'||c||'-' != ...

Maybe there are other drawbacks?

//Roger
-Ursprungligt meddelande- 
From: Imanuel 
Sent: Sunday, November 25, 2012 5:22 PM 
To: sqlite-users@sqlite.org 
Subject: Re: [sqlite] WAL and updates 


I'm not saying your statement is inefficient, I'm saying it's wrong
because it produces unwanted results.

If the fields a,b,c ('12','34','56') should be updated to
('1','2345','6') your statement would fail instead of doing the expected
update.

Which means with every false hit it has less data to write and thus is
faster because of the false hits (instead of "even with").

Imanuel



Am 25.11.2012 17:13, schrieb Simon Slavin:


On 25 Nov 2012, at 4:11pm, Imanuel  wrote:


Hi Keith


UPDATE user SET a=1,b=2,c=3 WHERE a||b||c!=1||2||3;


It seems to me that this is not reliable.
Think the the following text values:
a='12'
b='34'
c='56'

If you want to update these values to:
a='1'
b='2345'
c='6'

Then your statement would not update because '123456' = '123456'.


You're quite right, but in some cases it's sufficiently faster than doing

WHERE a!=1 OR b!=2 OR c!=3

that even with the false hits it takes less time to process.

Simon.
___
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


Re: [sqlite] WAL and updates

2012-11-25 Thread Imanuel
I'm not saying your statement is inefficient, I'm saying it's wrong
because it produces unwanted results.

If the fields a,b,c ('12','34','56') should be updated to
('1','2345','6') your statement would fail instead of doing the expected
update.

Which means with every false hit it has less data to write and thus is
faster because of the false hits (instead of "even with").

Imanuel



Am 25.11.2012 17:13, schrieb Simon Slavin:
> 
> On 25 Nov 2012, at 4:11pm, Imanuel  wrote:
> 
>> Hi Keith
>>
>>> UPDATE user SET a=1,b=2,c=3 WHERE a||b||c!=1||2||3;
>>
>> It seems to me that this is not reliable.
>> Think the the following text values:
>> a='12'
>> b='34'
>> c='56'
>>
>> If you want to update these values to:
>> a='1'
>> b='2345'
>> c='6'
>>
>> Then your statement would not update because '123456' = '123456'.
> 
> You're quite right, but in some cases it's sufficiently faster than doing
> 
> WHERE a!=1 OR b!=2 OR c!=3
> 
> that even with the false hits it takes less time to process.
> 
> Simon.
> ___
> 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


Re: [sqlite] WAL and updates

2012-11-25 Thread Simon Slavin

On 25 Nov 2012, at 4:11pm, Imanuel  wrote:

> Hi Keith
> 
>> UPDATE user SET a=1,b=2,c=3 WHERE a||b||c!=1||2||3;
> 
> It seems to me that this is not reliable.
> Think the the following text values:
> a='12'
> b='34'
> c='56'
> 
> If you want to update these values to:
> a='1'
> b='2345'
> c='6'
> 
> Then your statement would not update because '123456' = '123456'.

You're quite right, but in some cases it's sufficiently faster than doing

WHERE a!=1 OR b!=2 OR c!=3

that even with the false hits it takes less time to process.

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


Re: [sqlite] WAL and updates

2012-11-25 Thread Imanuel
Hi Keith

> UPDATE user SET a=1,b=2,c=3 WHERE a||b||c!=1||2||3;

It seems to me that this is not reliable.
Think the the following text values:
a='12'
b='34'
c='56'

If you want to update these values to:
a='1'
b='2345'
c='6'

Then your statement would not update because '123456' = '123456'.

Greetings



Am 25.11.2012 17:04, schrieb Simon Slavin:
> 
> On 25 Nov 2012, at 10:46am, Keith Chew  wrote:
> 
>> I found that when an update SQL is issued against a table, the WAL file
>> gets updated with the new record, even though the record is exactly the
>> same as the current record.
>>
>> [snip]
>>
>> Is there a specific reason for this? Is there a way to improve this by not
>> inserting the record into the WAL file if the final record is not changed?
> 
> I think it would take SQLite a lot of time to read every row to see whether 
> the UPDATE command will change it before generating the new entry.  Most 
> people's code wouldn't issue such a command under those circumstances.  
> Richard's suggesting of
> 
>> UPDATE user SET user_name='Keith' WHERE user_name!='Keith';
> 
> is what you're asking for.  With that many columns (which is unusual, 
> generally you should be able to keep an entire schema in your head) you can 
> either check them one by one, or concatenate them all together and check to 
> see that the long concatenation hasn't changed:
> 
> UPDATE user SET a=1,b=2,c=3 WHERE a||b||c!=1||2||3;
> 
> I seem to remember that this is a database where you have every column, of 40 
> to 50 columns, indexed.  This is also unusual, and not something that SQLite 
> is optimized for, and you're going to get unusual results from it.
> 
> Simon.
> ___
> 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


Re: [sqlite] WAL and updates

2012-11-25 Thread Simon Slavin

On 25 Nov 2012, at 10:46am, Keith Chew  wrote:

> I found that when an update SQL is issued against a table, the WAL file
> gets updated with the new record, even though the record is exactly the
> same as the current record.
> 
> [snip]
> 
> Is there a specific reason for this? Is there a way to improve this by not
> inserting the record into the WAL file if the final record is not changed?

I think it would take SQLite a lot of time to read every row to see whether the 
UPDATE command will change it before generating the new entry.  Most people's 
code wouldn't issue such a command under those circumstances.  Richard's 
suggesting of

> UPDATE user SET user_name='Keith' WHERE user_name!='Keith';

is what you're asking for.  With that many columns (which is unusual, generally 
you should be able to keep an entire schema in your head) you can either check 
them one by one, or concatenate them all together and check to see that the 
long concatenation hasn't changed:

UPDATE user SET a=1,b=2,c=3 WHERE a||b||c!=1||2||3;

I seem to remember that this is a database where you have every column, of 40 
to 50 columns, indexed.  This is also unusual, and not something that SQLite is 
optimized for, and you're going to get unusual results from it.

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


Re: [sqlite] WAL and updates

2012-11-25 Thread Kees Nuyt
On Mon, 26 Nov 2012 00:16:39 +1300, Keith Chew 
wrote:

>Hi Richard
>
>
>>
>> UPDATE user SET user_name='Keith' WHERE user_name!='Keith';
>>
>>
>>
>The example I provided was simplified only to explain the scenario. In a
>production environment, there are over 40-50 columns, and the suggested
>workaround above is impractical.

Yet it is the way to do this in SQL.
It is only impractical if you write the code by hand, perhaps you should
generate it instead. Use the output of PRAGMA table_info(yourtablename)
for the code generator to make the column list dynamic.

Or create a BEFORE UPDATE trigger that takes care of it and
RAISE(IGNORE,'Nothing to do') when there's nothing to do.


-- 
Groet, Cordialement, Pozdrawiam, Regards,

Kees Nuyt

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


Re: [sqlite] WAL and updates

2012-11-25 Thread Keith Chew
Hi Richard


>
> UPDATE user SET user_name='Keith' WHERE user_name!='Keith';
>
>
>
The example I provided was simplified only to explain the scenario. In a
production environment, there are over 40-50 columns, and the suggested
workaround above is impractical.

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


Re: [sqlite] WAL and updates

2012-11-25 Thread Richard Hipp
On Sun, Nov 25, 2012 at 5:46 AM, Keith Chew  wrote:

> Hi
>
> I found that when an update SQL is issued against a table, the WAL file
> gets updated with the new record, even though the record is exactly the
> same as the current record.
>
> Eg user table has 1 record with user_name = 'Keith'. Issuing this SQL will
> increase the WAL file:
>
> update user set user_name='Keith';
>
> Issuing it multiple times will keep increasing the size of the WAL file
> each time.
>
> Yet, the connection.getChanges() returns 0.
>
> Is there a specific reason for this? Is there a way to improve this by not
> inserting the record into the WAL file if the final record is not changed?
>

UPDATE user SET user_name='Keith' WHERE user_name!='Keith';


>
> Regards
> Keith
> ___
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>



-- 
D. Richard Hipp
d...@sqlite.org
___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


[sqlite] WAL and updates

2012-11-25 Thread Keith Chew
Hi

I found that when an update SQL is issued against a table, the WAL file
gets updated with the new record, even though the record is exactly the
same as the current record.

Eg user table has 1 record with user_name = 'Keith'. Issuing this SQL will
increase the WAL file:

update user set user_name='Keith';

Issuing it multiple times will keep increasing the size of the WAL file
each time.

Yet, the connection.getChanges() returns 0.

Is there a specific reason for this? Is there a way to improve this by not
inserting the record into the WAL file if the final record is not changed?

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