Thanks very much indeed for this. SQLite is like an onion; just when I think 
I’ve got to the last layer and understood it, I find there’s another layer to 
peel back and understand…

Best wishes,

Hamish

> On 4 Jul 2016, at 11:08 am, Hick Gunter <h...@scigames.at> wrote:
> 
> Creating a trigger causes SQLite to insert a row into the sqlite_master table 
> which contains the text you supply for the trigger. No code is generated at 
> this time. You can verify this by creating a trigger that references 
> undefined fields. It willl succeed. But entering a statement that references 
> the trigger will fail with an undefined field error.
> 
> When preparing a statement, SQLite will check for any triggers defined on the 
> referenced tables, prepare the appropriate "trigger programs" and insert 
> calls to these in the original "statement program".
> 
> A simple UPDATE <table> set <field>=<value> where <key_condition> will 
> translate into about 40 instructions; adding your trigger adds an additional 
> estimated 400 instructions of trigger program.
> 
> Basically, triggers are compiled into the statements that MAY cause them to 
> fire; the WHEN clause is evaluated within the context of the trigger, even if 
> the trigger does not fire at all.
> 
> -----Ursprüngliche Nachricht-----
> Von: sqlite-users-boun...@mailinglists.sqlite.org 
> [mailto:sqlite-users-boun...@mailinglists.sqlite.org] Im Auftrag von Hamish 
> Symington
> Gesendet: Montag, 04. Juli 2016 11:29
> An: SQLite mailing list <sqlite-users@mailinglists.sqlite.org>
> Betreff: Re: [sqlite] Trigger slowness even when it's not fired
> 
> Hi there,
> 
>> How many times are you preparing the update statement? Maybe you are just 
>> measuring the effort required to prepare 55000 UPDATE statements.
> OK, this sounds plausible. But given the trigger doesn’t even fire, why does 
> the statement need to be prepared? Is it not prepared just before running?
> 
>> What is the purpose of counting all the rows of several tables before firing 
>> the trigger? If you are attempting to avoid running UPDATE on an empty 
>> table, then you are failing. The trigger will fire as soon as any one of the 
>> mentioned tables has at least one row, without guaranteeing that the other 
>> tables are not empty.
> In the specific test scenario, all those tables are empty. It’s simply a way 
> of ensuring that this trigger doesn’t fire for this test. I’ve just tried it 
> with the following code, and it’s still slow, until I remove the update 
> statements, when it’s faster.
> 
> Hamish
> 
> 
> 
> // When ContactCalc's phone, email or website changes, update the phone, 
> email and website fields in // QuoteCalc, SaleCalc, PurchaseCalc and TxnCalc.
> // Also update GroupHead phone, email and web fields for QuoteCalc, SaleCalc, 
> PurchaseCalc, TxnCalc CREATE TRIGGER ContactCalcUpdate8 AFTER UPDATE OF 
> ContactCalc_Phone, ContactCalc_Email, ContactCalc_Website ON ContactCalc WHEN 
> (
>        Old.ContactCalc_Phone != New.ContactCalc_Phone
>        OR
>        Old.ContactCalc_Email != New.ContactCalc_Email
>        OR
>        Old.ContactCalc_Website != New.ContactCalc_Website
> )
> 
> AND 1=0
> 
> BEGIN
> 
>        INSERT INTO TriggerLog( TriggerLog_Name ) VALUES 
> ('ContactCalcUpdate8');
> 
>        … as before ...
> 
> 
>> 
>> -----Ursprüngliche Nachricht-----
>> Von: sqlite-users-boun...@mailinglists.sqlite.org
>> [mailto:sqlite-users-boun...@mailinglists.sqlite.org] Im Auftrag von
>> Hamish Symington
>> Gesendet: Montag, 04. Juli 2016 10:27
>> An: sqlite-users@mailinglists.sqlite.org
>> Betreff: [sqlite] Trigger slowness even when it's not fired
>> 
>> Hello,
>> 
>> I have a curious situation involving a trigger, which I’m at a loss to 
>> explain. I’m wondering if someone who knows more about the insides of SQLite 
>> can tell me more about why it’s happening. I’m running SQLite 3.8.7.
>> 
>> The trigger code is at the bottom of this email. It’s a straightforward 
>> AFTER UPDATE trigger, firing when any of three fields is updated and when 
>> the old value is not the same as the new value for any of those fields. 
>> There’s also a test I’ve put in there to make sure that some tables which 
>> I’m looking to update are not empty.
>> 
>> The table TriggerLog is a table I’ve added for testing. If the trigger 
>> fires, a row is inserted into the log. I have tested that this works when 
>> the trigger fires.
>> 
>> There are then a number of UPDATE statements to set flags on other tables. 
>> In the circumstances I’m running this in at the moment, there are no rows in 
>> QuoteCalc, SaleCalc, TxnCalc etc., so the trigger’s code won’t actually 
>> fire. I have verified this by inspecting TriggerLog after the text; there 
>> are no rows reporting that ContactCalcUpdate8 has fired.
>> 
>> During the test, a row on ContactCalc has one of its ContactCalc_Phone, 
>> ContactCalc_Email or ContactCalc_Website fields updated. This occurs on 
>> various rows of ContactCalc approximately 5,000 times. This stage of the 
>> test takes approximately 22 seconds.
>> 
>> If I remove all of the UPDATE rows from this trigger, and make no other 
>> changes, the test takes approximately 12 seconds.
>> 
>> I don’t understand why removing code from the body of a trigger which 
>> doesn’t fire makes things faster.
>> 
>> I have also tried replacing the WHERE clauses of all of the UPDATE 
>> statements with WHERE 1=0 to eliminate the possibility of the IN statement 
>> being the culprit; it’s still slow.
>> 
>> I would very much like to understand what’s going on here; perhaps someone 
>> can enlighten me.
>> 
>> Thanks,
>> 
>> Hamish
>> 
>> 
>> 
>> 
>> // When ContactCalc's phone, email or website changes, update the
>> phone, email and website fields in // QuoteCalc, SaleCalc, PurchaseCalc and 
>> TxnCalc.
>> // Also update GroupHead phone, email and web fields for QuoteCalc,
>> SaleCalc, PurchaseCalc, TxnCalc CREATE TRIGGER ContactCalcUpdate8
>> AFTER UPDATE OF ContactCalc_Phone, ContactCalc_Email,
>> ContactCalc_Website ON ContactCalc WHEN (
>>       Old.ContactCalc_Phone != New.ContactCalc_Phone
>>       OR
>>       Old.ContactCalc_Email != New.ContactCalc_Email
>>       OR
>>       Old.ContactCalc_Website != New.ContactCalc_Website
>> )
>> 
>> AND
>> (
>>       (
>>               SELECT COUNT(QuoteCalc_QuoteUUID) FROM QuoteCalc
>>       ) > 0
>>       OR
>>       (
>>               SELECT COUNT(SaleCalc_SaleUUID) FROM SaleCalc
>>       ) > 0
>>       OR
>>       (
>>               SELECT COUNT(PurchaseCalc_PurchaseUUID) FROM PurchaseCalc
>>       ) > 0
>>       OR
>>       (
>>               SELECT COUNT(TxnCalc_TxnUUID) FROM TxnCalc
>>       ) > 0
>> )
>> 
>> BEGIN
>> 
>>       INSERT INTO TriggerLog( TriggerLog_Name ) VALUES
>> ('ContactCalcUpdate8');
>> 
>> 
>>       UPDATE QuoteCalc
>>       SET QuoteCalc_UpdateContactFlag = 1
>>       WHERE QuoteCalc_ContactUUID = New.ContactCalc_ContactUUID;
>> 
>> 
>>       UPDATE SaleCalc
>>       SET SaleCalc_UpdateBillingContactFlag = 1
>>       WHERE SaleCalc_SaleUUID IN
>>       (
>>               SELECT Sale_UUID
>>               FROM Sale
>>               WHERE Sale_BillingContactUUID = New.ContactCalc_ContactUUID
>>       );
>> 
>>       UPDATE SaleCalc
>>       SET SaleCalc_UpdateShippingContactFlag = 1
>>       WHERE SaleCalc_SaleUUID IN
>>       (
>>               SELECT Sale_UUID
>>               FROM Sale
>>               WHERE Sale_ShippingContactUUID = New.ContactCalc_ContactUUID
>>       );
>> 
>> 
>>       UPDATE TxnCalc
>>       SET TxnCalc_UpdateContactFlag = 1
>>       WHERE TxnCalc_TxnUUID IN
>>       (
>>               SELECT TxnCalc_TxnUUID
>>               FROM TxnCalc
>>               WHERE TxnCalc_ContactUUID = New.ContactCalc_ContactUUID
>>       );
>> 
>> 
>>       UPDATE PurchaseCalc
>>       SET PurchaseCalc_UpdateContactFlag = 1
>>       WHERE PurchaseCalc_PurchaseUUID IN
>>       (
>>               SELECT PurchaseCalc_PurchaseUUID
>>               FROM PurchaseCalc
>>               WHERE PurchaseCalc_ContactUUID = New.ContactCalc_ContactUUID
>>       );
>> 
>> 
>>       UPDATE ContactCalc
>>       SET ContactCalc_UpdateGroupHeadFlag = 1
>>       WHERE ContactCalc_ContactUUID IN
>>       (
>>               SELECT Contact_UUID
>>               FROM Contact
>>               WHERE Contact_LinkedContactUUID = New.ContactCalc_ContactUUID
>>       );
>> 
>> 
>> 
>>       UPDATE QuoteCalc
>>       SET QuoteCalc_UpdateGroupHeadFlag = 1
>>       WHERE QuoteCalc_QuoteUUID IN
>>       (
>>               SELECT Quote_UUID
>>               FROM Quote,
>>               Contact
>>               WHERE Quote_ContactUUID = Contact_UUID
>>               AND Contact_LinkedContactUUID = New.ContactCalc_ContactUUID
>>       );
>> 
>> 
>>       UPDATE SaleCalc
>>       SET SaleCalc_UpdateBillingGroupHeadFlag = 1
>>       WHERE SaleCalc_SaleUUID IN
>>       (
>>               SELECT Sale_UUID
>>               FROM Sale,
>>               Contact
>>               WHERE Sale_BillingContactUUID = Contact_UUID
>>               AND Contact_LinkedContactUUID =
>> New.ContactCalc_ContactUUID
>> 
>>       );
>> 
>> 
>> 
>>       UPDATE SaleCalc
>>       SET SaleCalc_UpdateShippingGroupHeadFlag = 1
>>       WHERE SaleCalc_SaleUUID IN
>>       (
>>               SELECT Sale_UUID
>>               FROM Sale,
>>               Contact
>>               WHERE Sale_ShippingContactUUID = Contact_UUID
>>               AND Contact_LinkedContactUUID =
>> New.ContactCalc_ContactUUID
>> 
>>       );
>> 
>> 
>>       UPDATE TxnCalc
>>       SET TxnCalc_UpdateGroupHeadFlag = 1
>>       WHERE TxnCalc_TxnUUID IN
>>       (
>>               SELECT Txn_UUID
>>               FROM Txn,
>>               Contact
>>               WHERE Txn_ContactUUID = Contact_UUID
>>               AND Contact_LinkedContactUUID = New.ContactCalc_ContactUUID
>>       );
>> 
>> 
>> 
>>       UPDATE PurchaseCalc
>>       SET PurchaseCalc_UpdateGroupHeadFlag = 1
>>       WHERE PurchaseCalc_PurchaseUUID IN
>>       (
>>               SELECT Purchase_UUID
>>               FROM Purchase,
>>               Contact
>>               WHERE Purchase_ContactUUID = Contact_UUID
>>               AND Contact_LinkedContactUUID = New.ContactCalc_ContactUUID
>>       );
>> 
>> END;
>> _______________________________________________
>> sqlite-users mailing list
>> sqlite-users@mailinglists.sqlite.org
>> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>> 
>> 
>> ___________________________________________
>> Gunter Hick
>> Software Engineer
>> Scientific Games International GmbH
>> FN 157284 a, HG Wien
>> Klitschgasse 2-4, A-1130 Vienna, Austria
>> Tel: +43 1 80100 0
>> E-Mail: h...@scigames.at
>> 
>> This communication (including any attachments) is intended for the use of 
>> the intended recipient(s) only and may contain information that is 
>> confidential, privileged or legally protected. Any unauthorized use or 
>> dissemination of this communication is strictly prohibited. If you have 
>> received this communication in error, please immediately notify the sender 
>> by return e-mail message and delete all copies of the original 
>> communication. Thank you for your cooperation.
>> 
>> 
>> _______________________________________________
>> sqlite-users mailing list
>> sqlite-users@mailinglists.sqlite.org
>> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
> 
> _______________________________________________
> sqlite-users mailing list
> sqlite-users@mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
> 
> 
> ___________________________________________
> Gunter Hick
> Software Engineer
> Scientific Games International GmbH
> FN 157284 a, HG Wien
> Klitschgasse 2-4, A-1130 Vienna, Austria
> Tel: +43 1 80100 0
> E-Mail: h...@scigames.at
> 
> This communication (including any attachments) is intended for the use of the 
> intended recipient(s) only and may contain information that is confidential, 
> privileged or legally protected. Any unauthorized use or dissemination of 
> this communication is strictly prohibited. If you have received this 
> communication in error, please immediately notify the sender by return e-mail 
> message and delete all copies of the original communication. Thank you for 
> your cooperation.
> 
> 
> _______________________________________________
> sqlite-users mailing list
> sqlite-users@mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

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

Reply via email to