Slow write to sqlite on usb sticks

Terry Judd terry.judd at unimelb.edu.au
Thu Apr 26 17:38:57 EDT 2012


Wow, thanks Pete - I'll definitely give this method a try.

Terry..

On 27/04/2012, at 3:38 AM, "Peter Haworth" <pete at lcsql.com> wrote:

> Hi Terry,
> You can still do individual INSERTS, just need a few lines of extra code at
> the start and end of your code.  Here's an amended version of your code
> with the BEGIN/ROLLBACK/COMMIT in place.
> 
> put the cUpdateMessagesSQL of this cd into tSQL # my insert statement
> put revOpenDatabase("sqlite", pLocalPath, , , , ) into connectionID
> 
> --- Start an sqlite transaction
> revExecuteSQL connectionID,"BEGIN TRANSACTION"
> 
>  repeat for each line tRecord in pData # 1 message per line
>     # do some formatting stuff here
>     put merge(tSQL) into tSQL1
>     revExecuteSQL connectionID, tSQL1
> 
>     --Check for an error and back out the INSERTS
>     if the result is not an integer then
>        revExecuteSQL connectionID,"ROLLBACK"
>        -- Do whatever error tidy up is necessary here
>        exit top
>     end if
> 
>  end repeat
> 
>  -- Commit the INSERTs to disk
>  revExecuteSQL connectionID,"COMMIT"
> 
>  revCloseDatabase connectionID
> 
> SQLIte automatically starts/commits a transaction around individual
> statements if you haven't explicitly defined one with a BEGIN statement.
> There's disk i/o overhead involved in committing a transaction to disk and
> in your case, that overhead happens 40 times.  With the BEGIN/COMMIT in
> place, it only happens once and since the performance problem seems to be
> related to the slow transfer speed of USB drives, that should help.
> 
> The error check/ROLLBACK code will result in none of your INSERTs being
> written to disk if an error occurs on any of them.  With the code you have
> right now, if you got an error on an INSERT, you'd be left with the INSERTs
> processed before the error on disk.  Depending on your application, that
> may or may not be a problem.  If you'd rather leave the successful INSERTs
> in the database, remove the ROLLBACK line and change the "exit top" to
> "exit repeat", that way the COMMIT at the end of the repeat will still be
> executed.
> 
> If you have any indexes defined on columns in the table you're inserting
> into, that will incur extra disk overhead too.  Indexes are great for fast
> retrieval and normally their overhead during INSERTs isn't an issue but it
> seems that using a USB drive magnifies the effect of every disk i/o so that
> could be a problem.  Have you tried SELECTing data from this table yet?
> How does that performance compare?
> 
> As far as INSERTing multiple rows at the same time, SQLite recently
> enhanced the INSERT command to allow that.  You can specify multiple sets
> of column values with the VALUES clause:
> 
> INSERT INTO tableA (Col1,Col2) VALUES ('abc','def'),('ghi',jkl'), etc
> 
> I haven't experimented with that syntax yet to know if it provides any
> performance improvements.  I don't remember which version of SQLite that
> was introduced in so it's possible that Livecode doesn't include the
> required version of the SQLite library.
> 
> There are other things you can do to reduce i/o but I suggest you try the
> above first and see if it makes any difference.
> 
> Pete
> lcSQL Software <http://www.lcsql.com>
> 
> 
> 
> On Wed, Apr 25, 2012 at 11:20 PM, Terry Judd <terry.judd at unimelb.edu.au>wrote:
> 
>> 
>> On 26/04/2012, at 3:59 PM, Peter Haworth wrote:
>> 
>> Hi Terry,
>> Are you wrapping all 40 (or however many INSERTS) into one transaction?  By
>> which I mean there should be a BEGIN before the repeat loop starts and a
>> COMMIT after it finishes.  That definitely helps with performance and also
>> allows you to ROLLBACK if any of the INSERTs fail.
>> 
>> Hi Pete - thanks for the suggestion, at the moment I'm doing 40 separate
>> inserts, like this...
>> 
>> put the cUpdateMessagesSQL of this cd into tSQL # my insert statement
>> put revOpenDatabase("sqlite", pLocalPath, , , , ) into connectionID
>>  repeat for each line tRecord in pData # 1 message per line
>>     # do some formatting stuff here
>>     put merge(tSQL) into tSQL1
>>     revExecuteSQL connectionID, tSQL1
>>  end repeat
>>  revCloseDatabase connectionID
>> 
>> I doubt that would make fix the huge timing difference but worth a try if
>> you're not already doing it.
>> 
>> Yes, submitting them all at once could well help. I'm no SQL expert
>> though. How do I format the data and statement so that I'm submitting
>> multiple records at once?
>> 
>> Terry...
>> 
>> Only other thing I can think of is to try different combinations of LC and
>> the db on disk/USB - might narrow down which of the two is causing the
>> problem.
>> 
>> Pete
>> lcSQL Software <http://www.lcsql.com>
>> 
>> 
>> 
>> On Wed, Apr 25, 2012 at 6:57 PM, Terry Judd <terry.judd at unimelb.edu.au
>> <mailto:terry.judd at unimelb.edu.au>>wrote:
>> 
>> We're finding that it's very slow to write even small amounts of data from
>> Livecode to a sqlite file when the Livecode app and the db file are on a
>> usb stick (the db stores a local copy of the user's messages as they are
>> downloaded from a server). It seems to be something that is peculiar to the
>> usb setup as it works very quickly when run from a hard drive (less that 1
>> second for 40 messages vs 20-30 seconds on the usb stick). Has anyone
>> experienced anything similar and/or does anyone have any suggestions as to
>> how we might speed the process up?
>> 
>> I'm currently downloading the messages (as xml), converting them to an
>> array (from, to, subject, body, attachments etc.) and then writing each to
>> the sqlite db within a repeat loop and then closing the db connection.
>> 
>> Terry...
>> 
>> _______________________________________________
>> use-livecode mailing list
>> use-livecode at lists.runrev.com<mailto:use-livecode at lists.runrev.com>
>> Please visit this url to subscribe, unsubscribe and manage your
>> subscription preferences:
>> http://lists.runrev.com/mailman/listinfo/use-livecode
>> 
>> _______________________________________________
>> use-livecode mailing list
>> use-livecode at lists.runrev.com<mailto:use-livecode at lists.runrev.com>
>> Please visit this url to subscribe, unsubscribe and manage your
>> subscription preferences:
>> http://lists.runrev.com/mailman/listinfo/use-livecode
>> 
>> 
>> _______________________________________________
>> use-livecode mailing list
>> use-livecode at lists.runrev.com
>> Please visit this url to subscribe, unsubscribe and manage your
>> subscription preferences:
>> http://lists.runrev.com/mailman/listinfo/use-livecode
>> 
> _______________________________________________
> use-livecode mailing list
> use-livecode at lists.runrev.com
> Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
> http://lists.runrev.com/mailman/listinfo/use-livecode
> 





More information about the use-livecode mailing list