Received: from maia.hub.org (unknown [200.46.208.211]) by mail.postgresql.org (Postfix) with ESMTP id 8591A6325C9 for ; Thu, 4 Feb 2010 04:24:44 -0400 (AST) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.208.211]) (amavisd-maia, port 10024) with ESMTP id 18033-06 for ; Thu, 4 Feb 2010 08:24:30 +0000 (UTC) X-Greylist: delayed 01:54:25.732676 by SQLgrey-1.7.6 Received: from mail-px0-f194.google.com (mail-px0-f194.google.com [209.85.216.194]) by mail.postgresql.org (Postfix) with ESMTP id B96CF63014E for ; Thu, 4 Feb 2010 04:24:33 -0400 (AST) Received: by pxi32 with SMTP id 32so649956pxi.15 for ; Thu, 04 Feb 2010 00:24:32 -0800 (PST) MIME-Version: 1.0 Received: by 10.142.5.10 with SMTP id 10mr504224wfe.334.1265271871968; Thu, 04 Feb 2010 00:24:31 -0800 (PST) In-Reply-To: <603c8f071002031905w51dbea37y148284ea6546feda@mail.gmail.com> References: <603c8f071002031905w51dbea37y148284ea6546feda@mail.gmail.com> Date: Thu, 4 Feb 2010 03:24:31 -0500 Message-ID: Subject: Re: Slow query: table iteration (8.3) From: Glenn Maynard To: pgsql-performance@postgresql.org Content-Type: text/plain; charset=UTF-8 X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-2.599 tagged_above=-10 required=5 tests=BAYES_00=-2.599 X-Spam-Level: X-Archive-Number: 201002/77 X-Sequence-Number: 37498 On Wed, Feb 3, 2010 at 10:05 PM, Robert Haas wrote: > Rewriting it as a join will likely be faster still: > > SELECT r.id FROM stomp_steps s, stomp_round r WHERE (s.id IS NULL OR > r.steps_id = s.id) AND ($1 IS NULL OR r.user_card_id = $1) ORDER BY > r.score DESC LIMIT $2 That's not the same; this SELECT will only find the N highest scores, since the LIMIT applies to the whole results. Mine finds the highest scores for each stage (steps), since the scope of the LIMIT is each call of the function (eg. "find the top score for each stage" as opposed to "find the top five scores for each stage"). That's the only reason I used a function at all to begin with--I know no way to do this with a plain SELECT. eg. CREATE FUNCTION test(int) RETURNS SETOF INTEGER LANGUAGE SQL AS $$ SELECT generate_series(100 * $1, 100 * $1 + 5) LIMIT 2; $$; CREATE TABLE test_table(id integer primary key); INSERT INTO test_table SELECT generate_series(1, 5); SELECT test(t.id) FROM test_table t; If there's a way to do this without a helper function (that can optimize to index scans--I'm not sure 8.4's windowing did, need to recheck), I'd really like to know it. > And they eliminate overhead. I assumed that function calls within a SELECT would be inlined for optimization before reaching the planner--that's why I was surprised when it was falling back on a seq scan, and not optimizing for the context. I'm using 8.3. I see "Inline simple set-returning SQL functions in FROM clauses" in the 8.4 changelog; I'm not sure if that applies to this, since this set-returning SQL function isn't in the FROM clause. -- Glenn Maynard