Received: from localhost (unknown [200.46.208.211]) by mail.postgresql.org (Postfix) with ESMTP id 2526263334D for ; Wed, 23 Dec 2009 09:01:34 -0400 (AST) Received: from mail.postgresql.org ([200.46.204.86]) by localhost (mx1.hub.org [200.46.208.211]) (amavisd-maia, port 10024) with ESMTP id 11548-06 for ; Wed, 23 Dec 2009 13:01:16 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from smtp-out26.alice.it (smtp-out26.alice.it [85.33.2.26]) by mail.postgresql.org (Postfix) with ESMTP id 08DD163283B for ; Wed, 23 Dec 2009 09:01:22 -0400 (AST) Received: from FBCMMO02.fbc.local ([192.168.68.196]) by smtp-out26.alice.it with Microsoft SMTPSVC(6.0.3790.3959); Wed, 23 Dec 2009 14:01:19 +0100 Received: from FBCMCL01B05.fbc.local ([192.168.69.86]) by FBCMMO02.fbc.local with Microsoft SMTPSVC(6.0.3790.3959); Wed, 23 Dec 2009 14:01:18 +0100 Received: from lan.webthatworks.it ([79.0.145.79]) by FBCMCL01B05.fbc.local with Microsoft SMTPSVC(6.0.3790.3959); Wed, 23 Dec 2009 14:01:18 +0100 Received: from dawn.webthatworks.it (dawn.webthatworks.it [192.168.1.12]) by lan.webthatworks.it (Postfix) with ESMTP id 7027630056A for ; Wed, 23 Dec 2009 14:01:17 +0100 (CET) Received: from dawn.webthatworks.it (localhost [127.0.0.1]) by dawn.webthatworks.it (Postfix) with ESMTP id 3D2B13DA93 for ; Wed, 23 Dec 2009 14:01:17 +0100 (CET) Date: Wed, 23 Dec 2009 14:01:16 +0100 From: Ivan Sergio Borgonovo Cc: pgsql-sql@postgresql.org Subject: Re: short-cutting if sum()>constant Message-ID: <20091223140116.1c79d821@dawn.webthatworks.it> In-Reply-To: <162867790912230352v5b6e395fm1880111c04eaa626@mail.gmail.com> References: <20091222133527.3007bd96@dawn.webthatworks.it> <162867790912221147r7e3041fej44332a05faf915d6@mail.gmail.com> <20091223000031.54ad09b5@dawn.webthatworks.it> <20091223010940.51c5c069@dawn.webthatworks.it> <20091223024635.48d66554@dawn.webthatworks.it> <162867790912222338v73261b73u5c4e88a5ce85918f@mail.gmail.com> <20091223115628.1709caf5@dawn.webthatworks.it> <162867790912230352v5b6e395fm1880111c04eaa626@mail.gmail.com> Organization: http://www.webthatworks.it X-Mailer: Claws Mail 3.7.3 (GTK+ 2.18.5; x86_64-pc-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-OriginalArrivalTime: 23 Dec 2009 13:01:18.0225 (UTC) FILETIME=[044FB810:01CA83D0] X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-1.69 tagged_above=-10 required=5 tests=AWL=-0.383, BAYES_00=-2.599, MISSING_HEADERS=1.292 X-Spam-Level: X-Archive-Number: 200912/74 X-Sequence-Number: 33512 On Wed, 23 Dec 2009 12:52:38 +0100 Pavel Stehule wrote: > The problem is massive cycle. Plpgsql really isn't language for > this. This interpret missing own arithmetic unit. So every > expression is translated to SELECT statement > > IF a > c ~ SELECT a > c > a = a + 1 ~ SELECT a + 1 > these queries are executed in some special mode, but still it is > more expensive than C a = a + 1 I didn't get it. I'd expect that since plpgsql should shere SQL data types it could map easily something like if (a>b) then or a := a +b and something like a for in query loop was going to be highly optimised as well. plpgsql should be the most tightly bounded language to the internals of pg SQL. > > select sum(a) from data; takes 1999.492 ms. > > select count(*) from data; takes 1612.039 ms > it is slower, because there is one NULL test more. That didn't came as a surprise. It was there for comparison. > PLpgSQL quietly uses cursors for FOR SELECT, your plperl uses I didn't notice. That was my first plperl function in my life. Anyway that means that that test didn't say anything about interpreter speed and duck typing. > > Anyway I'm not able to justify the difference in speed between > > plpgsql and your solution in such case unless plpgsql is > > switching back and forward between binary data and their text > > representation. It would be nice if someone that know plpgsql > > internals explain where the cost comes from. > I thing so most expensive part in your plpgsql code is two > expression. I didn't understand. What's the reason the interpreter can't translate the if and the b := row._a + b; into something that very resemble compiled C? plpgsql is not doing anything different than: select count(*) from (select case when a>3 then 1 else 2 end, a+a from data limit 9000000) as f; One of the advantages of using plpgsql (and one annoyance too) is that variables are declared and plpgsql should know how to operate on them with native C code. BTW the best performer considering all constraints and data distribution seems to be the simplest one: select sum(s.a) from (select a from data where a>0 limit 9000000) s; Time: 2620.677 ms We've no negative int... and they are int, so they have to be no less than 1 if they are not 0. If I know there are no 0, the simplest version become even faster. When I randomly pick up values in [1,3] plpgsql and generate_series start to perform similarly but still the simplest version is leading. When the interval is in [1,6] the plpgsql becomes faster than the generate_series but the simplest version is still leading. Just when the interval is in [1,10] the plpgsql version and the simplest one becomes comparable. -- Ivan Sergio Borgonovo http://www.webthatworks.it