Re: Cursor fetch performance issue

Поиск
Список
Период
Сортировка
От Heikki Linnakangas
Тема Re: Cursor fetch performance issue
Дата
Msg-id 4F1FC428.5020703@enterprisedb.com
обсуждение исходный текст
Ответ на Re: Cursor fetch performance issue  (Tony Capobianco <tcapobianco@prospectiv.com>)
Список pgsql-performance
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

В списке pgsql-performance по дате отправления:

Предыдущее
От: Tomas Vondra
Дата:
Сообщение: Re: Can lots of small writes badly hamper reads from other tables?
Следующее
От: sridhar bamandlapally
Дата:
Сообщение: Re: PostgreSQL Parallel Processing !