Look this above! This will help you. I did't maked all test cases! /***************************************************************************/ CREATE TABLE account ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, initial_balance REAL );
CREATE TABLE movement ( id INTEGER PRIMARY KEY AUTOINCREMENT, account_id INTEGER REFERENCES account(id), payment UNIXEPOCH, amount REAL, balance REAL ); CREATE INDEX movent_idx01 ON movement (account_id, payment, id); DROP TRIGGER IF EXISTS movement_trg01; CREATE TRIGGER movement_trg01 AFTER DELETE ON movement FOR EACH ROW BEGIN UPDATE movement SET balance = balance - old.amount WHERE account_id = old.account_id AND (payment > old.payment OR (payment = old.payment AND id > old.id)); END; DROP TRIGGER IF EXISTS movement_trg02; CREATE TRIGGER movement_trg02 AFTER INSERT ON movement FOR EACH ROW BEGIN REPLACE INTO movement SELECT t1.id , t1.account_id , t1.payment , t1.amount , (COALESCE((SELECT balance FROM movement s1 WHERE s1.account_id = t1.account_id AND (s1.payment < t1.payment OR (s1.payment = t1.payment AND s1.id < t1.id)) GROUP BY s1.account_id HAVING s1.payment = MAX(s1.payment) AND s1.id = MAX(s1.id)), 0) + t1.amount) AS balance FROM movement t1 WHERE id = new.id; UPDATE movement SET balance = balance + new.amount WHERE account_id = new.account_id AND payment >= new.payment AND id > new.id; END; -- account and payment not changed DROP TRIGGER IF EXISTS movement_trg03; CREATE TRIGGER movement_trg03 AFTER UPDATE ON movement FOR EACH ROW WHEN ((old.account_id == new.account_id) AND (old.payment == new.payment) AND (new.amount != old.amount)) BEGIN UPDATE movement SET balance = balance + (new.amount - old.amount) WHERE account_id = old.account_id AND (payment > old.payment OR (payment = old.payment AND id >= old.id)); END; -- account_id or payment changed DROP TRIGGER IF EXISTS movement_trg03; CREATE TRIGGER movement_trg03 AFTER UPDATE ON movement FOR EACH ROW WHEN (((old.account_id != new.account_id) OR (old.payment != new.payment)) AND (new.amount != old.amount)) BEGIN -- same code as delete trigger UPDATE movement SET balance = balance - old.amount WHERE account_id = old.account_id AND (payment > old.payment OR (payment = old.payment AND id > old.id)); -- same code as insert REPLACE INTO movement SELECT t1.id , t1.account_id , t1.payment , t1.amount , (COALESCE((SELECT balance FROM movement s1 WHERE s1.account_id = t1.account_id AND (s1.payment < t1.payment OR (s1.payment = t1.payment AND s1.id < t1.id)) GROUP BY s1.account_id HAVING s1.payment = MAX(s1.payment) AND s1.id = MAX(s1.id)), 0) + t1.amount) AS balance FROM movement t1 WHERE id = new.id; UPDATE movement SET balance = balance + new.amount WHERE account_id = new.account_id AND payment >= new.payment AND id > new.id; END; INSERT INTO account (name, initial_balance) VALUES ('account 1', 0); INSERT INTO account (name, initial_balance) VALUES ('account 2', 100.0); INSERT INTO account (name, initial_balance) VALUES ('account 3', -100.0); INSERT INTO movement (account_id, payment, amount) VALUES (1, 1275503470, 123.45); INSERT INTO movement (account_id, payment, amount) VALUES (1, 1275503475, -24.10); INSERT INTO movement (account_id, payment, amount) VALUES (1, 1275503475, 50.00); UPDATE movement SET amount = 150.45 WHERE payment = 1275503470; -- to know what are the current balance of a account SELECT a.initial_balance + m.balance FROM account a JOIN movement m ON (a.id = m.account_id) GROUP BY m.account_id HAVING payment = MAX(payment); /***************************************************************************/ ----- Mensagem original ----- De: "Israel Lins Albuquerque" <israel...@polibrasnet.com.br> Para: steph...@mankowski.fr, "General Discussion of SQLite Database" <sqlite-users@sqlite.org> Enviadas: Terça-feira, 1 de Junho de 2010 17:12:02 Assunto: Re: [sqlite] Performance issue on view Create a new table to do this and add a trigger on op to make the sum. ----- Mensagem original ----- De: "Stéphane MANKOWSKI" <steph...@mankowski.fr> Para: sqlite-users@sqlite.org Enviadas: Terça-feira, 1 de Junho de 2010 16:57:16 Assunto: [sqlite] Performance issue on view Hi, In the this database file (http://skrooge.org/files/test.wrk), I created a table named "op" containing banking transactions. A transaction has: An unique id An account A date An amount I created a view named "v_op" with one more computed attribute named "balance". This attribute is the sum of all previous transactions (including current one) for the same account. My problem is that v_op is very slow. This is not usable. What can I do to improve performances ? PS: I don't want to compute "balance" attribute by code and save it in op balance due to the fact that I am using an undo/redo mechanism. Regards, Stephane _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users -- Atenciosamente, Israel Lins Albuquerque Desenvolvimento Polibrás Brasil Software Ltda. _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users -- Atenciosamente, Israel Lins Albuquerque Desenvolvimento Polibrás Brasil Software Ltda. _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users