X-Original-To: pgsql-performance-postgresql.org@localhost.postgresql.org Received: from localhost (unknown [200.46.204.144]) by svr1.postgresql.org (Postfix) with ESMTP id 6CADA52949 for ; Mon, 27 Jun 2005 23:37:53 -0300 (ADT) Received: from svr1.postgresql.org ([200.46.204.71]) by localhost (av.hub.org [200.46.204.144]) (amavisd-new, port 10024) with ESMTP id 81510-01 for ; Tue, 28 Jun 2005 02:37:44 +0000 (GMT) Received: from smtp001.bizmail.yahoo.com (smtp001.bizmail.yahoo.com [216.136.172.125]) by svr1.postgresql.org (Postfix) with SMTP id 7FEB0528A9 for ; Mon, 27 Jun 2005 23:37:42 -0300 (ADT) Received: from unknown (HELO ?192.168.3.41?) (david.mitchell@telogis.com@203.98.10.169 with plain) by smtp001.bizmail.yahoo.com with SMTP; 28 Jun 2005 02:37:43 -0000 Message-ID: <42C0B7EE.4040608@telogis.com> Date: Tue, 28 Jun 2005 14:37:34 +1200 From: David Mitchell User-Agent: Mozilla Thunderbird 1.0 (Windows/20041206) X-Accept-Language: en-us, en MIME-Version: 1.0 To: pgsql-performance@postgresql.org Subject: How can I speed up this function? Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Scanned: by amavisd-new at hub.org X-Archive-Number: 200506/517 X-Sequence-Number: 13154 We have the following function in our home grown mirroring package, but it isn't running as fast as we would like. We need to select statements from the pending_statement table, and we want to select all the statements for a single transaction (pending_trans) in one go (that is, we either select all the statements for a transaction, or none of them). We select as many blocks of statements as it takes to top the 100 statement limit (so if the last transaction we pull has enough statements to put our count at 110, we'll still take it, but then we're done). Here is our function: CREATE OR REPLACE FUNCTION dbmirror.get_pending() RETURNS SETOF dbmirror.pending_statement AS $BODY$ DECLARE count INT4; transaction RECORD; statement dbmirror.pending_statement; BEGIN count := 0; FOR transaction IN SELECT t.trans_id as ID FROM pending_trans AS t WHERE fetched = false ORDER BY trans_id LIMIT 50 LOOP update pending_trans set fetched = true where trans_id = transaction.id; FOR statement IN SELECT s.id, s.transaction_id, s.table_name, s.op, s.data FROM dbmirror.pending_statement AS s WHERE s.transaction_id = transaction.id ORDER BY s.id ASC LOOP count := count + 1; RETURN NEXT statement; END LOOP; IF count > 100 THEN EXIT; END IF; END LOOP; RETURN; END;$BODY$ LANGUAGE 'plpgsql' VOLATILE; Table Schemas: CREATE TABLE dbmirror.pending_trans ( trans_id oid NOT NULL, fetched bool DEFAULT false, CONSTRAINT pending_trans_pkey PRIMARY KEY (trans_id) ) WITHOUT OIDS; CREATE TABLE dbmirror.pending_statement ( id oid NOT NULL DEFAULT nextval('dbmirror.statement_id_seq'::text), transaction_id oid NOT NULL, table_name text NOT NULL, op char NOT NULL, data text NOT NULL, CONSTRAINT pending_statement_pkey PRIMARY KEY (id) ) WITHOUT OIDS; CREATE UNIQUE INDEX idx_stmt_tran_id_id ON dbmirror.pending_statement USING btree (transaction_id, id); Postgres 8.0.1 on Linux. Any Help would be greatly appreciated. Regards -- David Mitchell Software Engineer Telogis