Received: from magus.postgresql.org (magus.postgresql.org [87.238.57.229]) by mail.postgresql.org (Postfix) with ESMTP id 5235C12E1D35 for ; Wed, 25 Jan 2012 04:58:36 -0400 (AST) Received: from exprod7og101.obsmtp.com ([64.18.2.155]) by magus.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1Rpygb-0008Jo-GK for pgsql-performance@postgresql.org; Wed, 25 Jan 2012 08:58:36 +0000 Received: from mail-lpp01m010-f51.google.com ([209.85.215.51]) (using TLSv1) by exprod7ob101.postini.com ([64.18.6.12]) with SMTP ID DSNKTx/EK3M4RzEFECetSQ2TGjHmm5q6/vDw@postini.com; Wed, 25 Jan 2012 00:58:33 PST Received: by mail-lpp01m010-f51.google.com with SMTP id p5so2638669lag.10 for ; Wed, 25 Jan 2012 00:58:19 -0800 (PST) Received: by 10.112.102.37 with SMTP id fl5mr4187982lbb.95.1327481899121; Wed, 25 Jan 2012 00:58:19 -0800 (PST) Received: from [192.168.1.102] (dsl-hkibrasgw2-ff6cc300-200.dhcp.inet.fi. [88.195.108.200]) by mx.google.com with ESMTPS id pf12sm7579647lab.16.2012.01.25.00.58.17 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 25 Jan 2012 00:58:18 -0800 (PST) Message-ID: <4F1FC428.5020703@enterprisedb.com> Date: Wed, 25 Jan 2012 10:58:16 +0200 From: Heikki Linnakangas User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:8.0) Gecko/20120104 Icedove/8.0 MIME-Version: 1.0 To: Tony Capobianco CC: Pavel Stehule , Andy Colson , pgsql-performance@postgresql.org Subject: Re: Cursor fetch performance issue References: <1327437700.1968.10.camel@tony1.localdomain> <1327438657.1968.15.camel@tony1.localdomain> <4F1F1E7A.4080403@squeakycode.net> <1327440846.1968.20.camel@tony1.localdomain> In-Reply-To: <1327440846.1968.20.camel@tony1.localdomain> X-Gm-Message-State: ALoCoQmdU/jJsTiIL+0DfoNdJMYPZO81oHZ7ogHOzUQEnJChnKZNjPX0pYCQRmFKMDh3NtPMMCHM Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Pg-Spam-Score: -4.2 (----) X-Archive-Number: 201201/71 X-Sequence-Number: 46083 On 24.01.2012 23:34, Tony Capobianco wrote: > Here's the explain: > > pg=# explain select getMemberAdminPrevious_sp(247815829, 1,'test.email@hotmail.com', 'Email', 'Test'); > QUERY PLAN > ------------------------------------------ > Result (cost=0.00..0.26 rows=1 width=0) > (1 row) > > Time: 1.167 ms That's not very helpful. We'd need to see the plan of the query within the function, not the plan on invoking the function. The auto_explain contrib module with auto_explain_log_nested_statements=on might be useful to get that. > There was discussion of 'LIKE' v. '=' and wildcard characters are not > being entered into the $1 parameter. > > This is not generating a sql string. I feel it's something to do with > the fetch of the refcursor. The cursor is a larger part of a function: > > CREATE OR REPLACE FUNCTION PUBLIC.GETMEMBERADMINPREVIOUS_SP2 ( > p_memberid IN numeric, > p_websiteid IN numeric, > p_emailaddress IN varchar, > p_firstname IN varchar, > p_lastname IN varchar) > RETURNS refcursor AS $$ > DECLARE > ref refcursor; > l_sysdateid numeric; > BEGIN > l_sysdateid := sysdateid(); > if (p_memberid != 0) then > if (p_emailaddress IS NOT NULL) then > OPEN ref FOR > SELECT m.memberid, m.websiteid, m.emailaddress, > m.firstname, m.lastname, m.regcomplete, m.emailok > FROM members m > WHERE m.emailaddress LIKE p_emailaddress > AND m.changedate_id< l_sysdateid ORDER BY m.emailaddress, > m.websiteid; > end if; > end if; > Return ref; > EXCEPTION > WHEN NO_DATA_FOUND THEN > Return null; > END; > $$ LANGUAGE 'plpgsql'; The theory that the query takes a long time because "LIKE p_emailaddress" is not optimizeable by the planner seems the most likely to me. If you don't actually use any wildcards in the email, try replacing LIKE with =. If you do, then you can try the "OPEN ref FOR EXECUTE" syntax. That way the query is re-planned every time, and the planner can take advantage of the parameter value. That enables it to use an index on the email address column, when there isn't in fact any wildcards in the value, and also estimate the selectivities better which can lead to a better plan. Like this: CREATE OR REPLACE FUNCTION public.getmemberadminprevious_sp2(p_memberid numeric, p_websiteid numeric, p_emailaddress character varying, p_firstname character varying, p_lastname character varying) RETURNS refcursor LANGUAGE plpgsql AS $function$ DECLARE ref refcursor; l_sysdateid numeric; BEGIN l_sysdateid := sysdateid(); if (p_memberid != 0) then if (p_emailaddress IS NOT NULL) then OPEN ref FOR EXECUTE $query$ SELECT m.memberid, m.websiteid, m.emailaddress, m.firstname, m.lastname, m.regcomplete, m.emailok FROM members m WHERE m.emailaddress LIKE $1 AND m.changedate_id < $2 ORDER BY m.emailaddress, m.websiteid; $query$ USING p_emailaddress, l_sysdateid; end if; end if; Return ref; EXCEPTION WHEN NO_DATA_FOUND THEN Return null; END; $function$ -- Heikki Linnakangas EnterpriseDB http://www.enterprisedb.com