[Lazarus] RE : SQLite performance problem. Simple query takes toolong.
Howard Lee Harkness
howard.lee.harkness at gmail.com
Fri Jul 29 19:37:02 CEST 2011
Thank you for your reply. I found it very interesting. I switched the
code that I posted to the following (I refactored this so that I could
call from several different places, for inserts, updates, and
deletes):
procedure TfrmMain.ExecSQL(sql:string);
begin
FormDatabase.SQLite3Connection.ExecuteDirect(sql);
FormDatabase.SQLite3Connection.ExecuteDirect('commit');
FormDatabase.SQLite3Connection.ExecuteDirect('begin transaction');
end;
I suppose that I could use a query component in there, but I don't
know what difference that would make (this code is not presenting any
performance issues; see below), and I'm a bit confused about the
proper usage. There are some properties of TSQLQuery for which I have
been unable to locate usage examples.
DeleteSQL
InsertSQL
UpdateSQL
I also don't know how to use the IndexDefs, IndexFieldNames, or
IndexName properties. Every permutation of guesses I've tried either
get deleted by the IDE, or don't actually change anything that I can
detect. I have found some documentation on
http://free-pascal-general.1045716.n5.nabble.com/New-local-indexes-support-for-sqldb-td2817867.html
which might shed some light on those parameters.
A search on TSQLQuery.DeleteSQL brought up a reference to
http://community.freepascal.org:10000/bboards/message?message_id=275621&forum_id=24081
which partially answers a question *I* posed 4 years ago on that topic
(that was for a prior iteration of this same program, which I managed
to kluge together, then not look at again until last week). I see that
the wiki was updated to include a mention of the fact that DeleteSQL,
InsertSQL, and UpdateSQL can take parameters -- which is helpful
information (parameters can help performance), but the performance hit
that I am seeing is happening in a simple lookup (for which the
transaction stuff is not needed). Here's the code:
qClients.Close;
qClients.SQL.Text:=sql;
qClients.Open;
That part is pretty much in the form that you suggested. The Close is
taking 1 to 2 seconds, and the Open is taking a similar amount of
time. That does not seem reasonable, especially since the same code
using PostgreSQL executed those three statements on the same database
before a fast typist could hit the next key (I am incrementally
building the lookup sql). That makes me wonder if I need to change how
qClients is initialized. Here is the current setup of qClients:
object qClients: TSQLQuery
IndexName = 'DEFAULT_ORDER'
AutoCalcFields = False
Database = FormDatabase.SQLite3Connection
Transaction = FormDatabase.SQLTransaction
ReadOnly = False
Params = <>
left = 504
top = 64
end
I'm not seeing anything in there that I would recognize as a performance issue.
Here is the database form (user and password omitted):
object FormDatabase: TFormDatabase
Left = 473
Height = 240
Top = 169
Width = 184
Caption = 'FormDatabase'
LCLVersion = '0.9.30'
object SQLite3Connection: TSQLite3Connection
Connected = False
LoginPrompt = False
DatabaseName = 'C:\pruett\PascalDB\PruettClients.s3db'
KeepConnection = True
Transaction = SQLTransaction
Options = []
left = 53
top = 123
end
object SQLTransaction: TSQLTransaction
Active = False
Action = caNone
Database = SQLite3Connection
left = 53
top = 67
end
end
I found it interesting that the program could open and use the
database without the full path included, but the design-time part of
the IDE requires a full pathname to do the "active at design time"
trick. Not sure exactly how I guessed that.
I think I have a (ugly) workaround for the performance issue, but I
would like to do better. Further suggestions are welcome, and don't
worry about hurting my feelings; I realize that I'm not yet very
proficient in Lazarus, since I have used it only sporadically.
On Fri, Jul 29, 2011 at 9:13 AM, Ludo Brands <ludo.brands at free.fr> wrote:
>> I have established that the problem is not in SQLite, but has
>> to be in my code somewhere. I suspect it is related to the
>> transaction/commit problem I posted a few days ago, and I
>> plan to track that down today if I can. I need to finish this
>> application by tomorrow.
>>
>
> I read your previous messages again. By the looks of it you're using a very
> hybrid way of using SQLite3Connection trying to do things yourself that the
> components are supposed to do (starting transactions for example).
> Here is a basic example of inserting data with direct sql queries:
>
> -drop a TSQLite3Connection, a TSQLTransaction and a TSQLQuery on a form, a
> data module or create them in code.
> -set TSQLite3Connection properties to connect to your database
> -assign TSQLTransaction.Database to the TSQLite3Connection instance
> -assign TSQLQuery.Database to the TSQLite3Connection instance and
> TSQLQuery.Transaction to the SQLTransaction instance. Active:= False,
> SQL.Text:=''.
>
> Now to execute an insert query (assuming
> TSQLite3Connection.Connected:=true):
> SQLQuery.SQL.Text:=sql;
> SQLQuery.ExecSQL;
> SQLTransaction.CommitRetaining;
>
> That's it. SQLTransaction.CommitRetaining; does the COMMIT and a BEGIN to
> start a new transaction.
>
> Just to be complete, I'm using lazarus 0.9.31 svn with fpc 2.5.1 svn.
>
> Ludo
--
Howard Lee Harkness
(214) 390-4896
More information about the Lazarus
mailing list