Received: from maia.hub.org (unknown [200.46.204.183]) by mail.postgresql.org (Postfix) with ESMTP id 64EE0632B50 for ; Sat, 17 Oct 2009 08:38:21 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.183]) (amavisd-maia, port 10024) with ESMTP id 73668-01 for ; Sat, 17 Oct 2009 11:38:13 +0000 (UTC) Received: from news.hub.org (news.hub.org [200.46.204.72]) by mail.postgresql.org (Postfix) with ESMTP id 9A242632AB4 for ; Sat, 17 Oct 2009 08:38:13 -0300 (ADT) Received: from news.hub.org (news.hub.org [200.46.204.72]) by news.hub.org (8.14.3/8.14.3) with ESMTP id n9HBc2t2057021 for ; Sat, 17 Oct 2009 08:38:02 -0300 (ADT) (envelope-from news@news.hub.org) Received: (from news@localhost) by news.hub.org (8.14.3/8.14.3/Submit) id n9HBTPTl032170 for pgsql-sql@postgresql.org; Sat, 17 Oct 2009 08:29:25 -0300 (ADT) (envelope-from news) From: matthias schoeneich X-Newsgroups: pgsql.sql Subject: Re: Efficiency in Multiple Queries of Same Table in a PL/PgSQL Function Date: Sat, 17 Oct 2009 13:29:32 +0200 Organization: Hub.Org Networking Services Lines: 96 Message-ID: References: <302670f20910161927h688e13e7qd096e63e68b7ae6c@mail.gmail.com> <4AD93837.7030500@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Complaints-To: usenet@news.hub.org User-Agent: Thunderbird 2.0.0.23 (Windows/20090812) In-Reply-To: <4AD93837.7030500@gmail.com> To: pgsql-sql@postgresql.org X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0.001 tagged_above=-10 required=5 tests=BAYES_50=0.001 X-Spam-Level: X-Archive-Number: 200910/67 X-Sequence-Number: 33266 Hi, as you don't seem to need the sigma_*'s, you could calc the whole result with one query using: CREATE OR REPLACE FUNCTION poly_example2() RETURNS SETOF FLOAT8 AS $poly_example$ DECLARE f_result FLOAT8 := 0.0; i_rowcount INT := 0 ; BEGIN SELECT sum((RANDOM() * 100 ) * (term.i * term.i) + RANDOM() * (term.j * term.j) + term.k) + sum((RANDOM() * 53 ) * (term.i * term.i) +(RANDOM()* 5) * (term.j * term.j) + term.k) + sum( 96.232234 * (term.i * term.i) + 0.32322325 * (term.j * term.j) + term.k) , count(*) INTO f_result , i_rowcount FROM blah AS term; IF i_rowcount > 0 THEN RETURN NEXT f_result; ELSE RETURN NEXT 0; END IF; END; $poly_example$ LANGUAGE plpgsql STRICT IMMUTABLE; I've just put it in your plpgsql body to handle the case where table blah contains no rows. Matthias Rob Sargent schrieb: > I don't see anything in the assignment statements (sigma_* :=) which > would prevent one from doing all three of them within a single for > loop. In fact, written as is there's some chance the values of the > sigma_*s might change between repeated calls to the function since there > is no explicit ordering of the rows returned from table blah. Putting > all the assignments into a single select from blah would at least say > that the sigma values are from the same dataset per run. > > > As to efficiency in general, I would expect the entire table (~50 rows) > would be entirely in memory after the first select, but you plan triples > the time in the loop. This expense would likely only be noticeable if > the function itself is called /lots/. > > Gary Chambers wrote: >> All... >> >> In the poly_example function below, I am emulating an actual >> requirement by querying the same table three (3) times in order to >> derive a solution to a problem. Is this the best or most efficient >> and effective way to implement this? The table (which consists of >> only five (5) FLOAT8 columns) I'm querying contains less than 50 rows. >> Thanks in advance for any insight or criticisms you offer. >> >> CREATE OR REPLACE FUNCTION poly_example() RETURNS SETOF FLOAT8 AS >> $poly_example$ >> DECLARE >> term blah%ROWTYPE; >> sigma_l FLOAT8 := 0.0; >> sigma_b FLOAT8 := 0.0; >> sigma_r FLOAT8 := 0.0; >> >> BEGIN >> FOR term in SELECT * FROM blah LOOP >> sigma_l := sigma_l + (RANDOM() * 100) * (term.i * term.i) + >> RANDOM() * (term.j * term.j) + term.k; >> END LOOP; >> >> FOR term in SELECT * FROM blah LOOP >> sigma_b := sigma_b + (RANDOM() * 53) * (term.i * term.i) + >> (RANDOM() * 5) * (term.j * term.j) + term.k; >> END LOOP; >> >> FOR term in SELECT * FROM blah LOOP >> sigma_r := sigma_r + 96.232234 * (term.i * term.i) + >> 0.32322325 * (term.j * term.j) + term.k; >> END LOOP; >> >> RETURN NEXT sigma_l + sigma_b + sigma_r; >> END; >> $poly_example$ LANGUAGE plpgsql STRICT IMMUTABLE; >> >> -- Gary Chambers >> >> /* Nothing fancy and nothing Microsoft! */ >> >> > >