Re: Cursor fetch performance issue

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 24.01.2012 23:34, Tony Capobianco wrote:
Here's the explain:

pg=# explain select getMemberAdminPrevious_sp(247815829, 1,'test.email@xxxxxxxxxxx', '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

--
Sent via pgsql-performance mailing list (pgsql-performance@xxxxxxxxxxxxxx)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance


[Postgresql General]     [Postgresql PHP]     [PHP Users]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Yosemite]

  Powered by Linux