Received: from maia.hub.org (unknown [200.46.208.211]) by mail.postgresql.org (Postfix) with ESMTP id C6652634D75 for ; Thu, 22 Apr 2010 13:47:57 -0300 (ADT) 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 25954-01-3 for ; Thu, 22 Apr 2010 16:47:45 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mail-vw0-f46.google.com (mail-vw0-f46.google.com [209.85.212.46]) by mail.postgresql.org (Postfix) with ESMTP id 270F163FCB6 for ; Thu, 22 Apr 2010 11:12:01 -0300 (ADT) Received: by vws20 with SMTP id 20so255598vws.19 for ; Thu, 22 Apr 2010 07:11:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:in-reply-to:references :date:received:message-id:subject:from:to:cc:content-type; bh=CSJiyMjfGJHwy9kQEQirAKEC9mSN7WNubNu7UCpCj7Q=; b=lgT/TVHbe8PdoFZ/guExgtxcjzOveZK5iU+JropMPssECbNFGwqG/gFLLC1uAiP8S6 E4y8XkPx2o3IIYraIUDsiV2Upyx/+F2Tdspdgvx4E028Jzapkh+vUJjXFy6kimabDfVe 6KblWXPwWa+oGchYfj+6gUmPn6b0C5mfLQv3Y= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; b=mqSMcEpvgufClTj1in/InLglDGEvpHkVyZEgbhARK58HQN1kymtmzAZZEdM32gN5eq gjKdsUls2yLff8uGewoCJdAW1UBvsBa39jF7zTrS+aGDCdbLMZvDtFRc5KysvJaWw9aJ /aCJ4wsKvCtzoo7z/av1/Fw839yUhQdNExqRU= MIME-Version: 1.0 Received: by 10.220.99.10 with HTTP; Thu, 22 Apr 2010 07:11:59 -0700 (PDT) In-Reply-To: References: Date: Thu, 22 Apr 2010 10:11:59 -0400 Received: by 10.220.44.20 with SMTP id y20mr6835050vce.97.1271945519678; Thu, 22 Apr 2010 07:11:59 -0700 (PDT) Message-ID: Subject: Re: Replacing Cursors with Temporary Tables From: Merlin Moncure To: Eliot Gable Cc: pgsql-performance@postgresql.org Content-Type: text/plain; charset=ISO-8859-1 X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-1.162 tagged_above=-10 required=5 tests=AWL=-1.161, BAYES_20=-0.001 X-Spam-Level: X-Archive-Number: 201004/288 X-Sequence-Number: 38538 On Wed, Apr 21, 2010 at 4:16 PM, Eliot Gable wrote: > I have previously discussed my very long PL/PGSQL stored procedure on this > list. However, without getting into too many details, I have another > performance-related question. ok, here's a practical comparion: -- test data create table foo(foo_id int primary key); insert into foo select generate_series(1, 1000) v; create table bar(bar_id int, foo_id int references foo); create index bar_foo_id_idx on bar(foo_id); insert into bar select v, (v % 1000) + 1 from generate_series(1, 1000000) v; -- arrays create or replace function get_foobars(_foo_id int, _foo out foo, _bars out bar[]) returns record as $$ begin select * from foo where foo_id = _foo_id into _foo; select array(select bar from bar where foo_id = _foo_id) into _bars; end; $$ language plpgsql; select (unnest(_bars)).* from get_foobars(6); -- ~ 4ms on my box -- temp table create or replace function get_foobars(_foo_id int) returns void as $$ begin create temp table bars on commit drop as select * from bar where foo_id = _foo_id; end; $$ language plpgsql; begin; select get_foobars(6); -- ~ 3ms select * from bars; -- 1.6ms commit; -- 1ms The timings are similar, but the array returning case: *) runs in a single statement. If this is executed from the client that means less round trips *) can be passed around as a variable between functions. temp table requires re-query *) make some things easier/cheap such as counting the array -- you get to call the basically free array_upper() *) makes some things harder. specifically dealing with arrays on the client is a pain UNLESS you expand the array w/unnest() or use libpqtypes *) can nest. you can trivially nest complicated sets w/arrays *) does not require explicit transaction mgmt merlin