Unix Technical Forum

Re: dynamically generated SQL and planner/performance

This is a discussion on Re: dynamically generated SQL and planner/performance within the Pgsql General forums, part of the PostgreSQL category; --> Ivan Sergio Borgonovo wrote: > I've a lot of code that should call different functions according to > values ...


Go Back   Unix Technical Forum > Database Server Software > PostgreSQL > Pgsql General

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 04-10-2008, 12:22 AM
Albe Laurenz
 
Posts: n/a
Default Re: dynamically generated SQL and planner/performance

Ivan Sergio Borgonovo wrote:
> I've a lot of code that should call different functions according to
> values in tables.
>
> something like:
>
>
> create table FuncName(Name varchar(10), arg int);
>
> insert into FuncName values('ciro',5);
> insert into FuncName values('pino',7);
> insert into FuncName values('nano',11);
>
> create or replace function ciro(arg int, out res int) as
> $$
> begin
> res:=arg;
> return;
> end;
> $$ language plpgsql;
>
> create or replace function pino(arg int, out res int) as
> $$
> begin
> res:=arg*2;
> return;
> end;
> $$ language plpgsql;
>
> create or replace function nano(arg int, out res int) as
> $$
> begin
> res:=arg*4;
> return;
> end;
> $$ language plpgsql;
>
>
> create or replace function FBuilder(out res int) as
> $$
> declare
> statement varchar(256);
> _Name varchar(10);
> _arg int;
> begin
> select into _Name, _arg Name, arg from FuncName order by random();
> statement := ' select * from ' || _Name || '(' || _arg || ')';
> execute statement into res;
> return;
> end;
> $$ language plpgsql;
>
> select * from FBuilder();
>
> I don't understand which impact will have on the planner, caching
> etc... generating the statement dynamically.
>
> Will the execution of ciro, pino e nano be affected?
> Or will just the plan for executing FBuilder statement be affected?


The execution plan of dynamic queries from PL/pgSQL will not be cached;
the query will be prepared at execution time every time you execute it.

The plan for executing "select * from FBuilder()" will not be affected
by the SQL statements you execute from within FBuilder().
All you can do to hint at the planner that calling FBuilder() will be
expensive is (from version 8.3 on) to include a COST clause in the
CREATE FUNCTION statement.

Unless the dynamic statements are complicated or are called very often,
I would not worry too much about the additional cost of preparing the statement.

Yours,
Laurenz Albe

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

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 04-10-2008, 12:22 AM
Ivan Sergio Borgonovo
 
Posts: n/a
Default Re: dynamically generated SQL and planner/performance

On Fri, 21 Mar 2008 12:15:19 +0100
"Albe Laurenz" <laurenz.albe@wien.gv.at> wrote:

> The execution plan of dynamic queries from PL/pgSQL will not be
> cached; the query will be prepared at execution time every time you
> execute it.


Pardon my ignorance but I really have a very vague idea of what the
planner does and how it works.

Does the planner "compose" plans or does it have one plan for each
statement?

if I've nested functions what does the planner?

When I do select * from func(); explain analyse doesn't say much.

> The plan for executing "select * from FBuilder()" will not be
> affected by the SQL statements you execute from within FBuilder().
> All you can do to hint at the planner that calling FBuilder() will
> be expensive is (from version 8.3 on) to include a COST clause in
> the CREATE FUNCTION statement.


> Unless the dynamic statements are complicated or are called very
> often, I would not worry too much about the additional cost of
> preparing the statement.


The generated statement is very similar to the one I posted.
I just have to call the right function according to what I find in a
table.

The work flow is something like:
- user write in a table a choice (int)
- each int is associated with a plpgsql function
- the statement is assembled, executed and the the specific function
result is returned in a way similar to the one of FBuilder

the dynamically assembled query is very similar to the one shown in
FBuilder.
There is a simple select that fetch the function name and an argument.
It is a bit more complicated than the one shown since the arguments
are taken from different tables and there is a where clause.

But nothing far from a:

[A]
select a.Name, b.arg from FuncTable a join Args b on b.id=a.id where
b.val>7;

then the statement is really as:

[b]
statement := ' select * from ' || _Name || '(' || _arg || ')';

Just I fetch a couple more args.

and then I actually do a

[C]
execute statement into res;
return;

Now I'd like what I'm loosing using dynamic queries.

Can I say that:
- I won't lose anything in step [A]
- I won't lose anything in step [b]
- I'll lose something in step [C]
- I won't lose anything in the actual execution of function _Name(...)

My main concern is _Name(...) _Name[s] functions are all made with
static statements but they are relatively critical since most use
aggregates, a bunch of join and sub-queries... so no matter if the
'select * from ' || _Name ...
is not optimised I'd like to know if the execution of what's inside
each _Name function will be.

thanks

--
Ivan Sergio Borgonovo
http://www.webthatworks.it


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

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3 (permalink)  
Old 04-10-2008, 12:22 AM
Alvaro Herrera
 
Posts: n/a
Default Re: dynamically generated SQL and planner/performance

Ivan Sergio Borgonovo wrote:
> On Fri, 21 Mar 2008 12:15:19 +0100
> "Albe Laurenz" <laurenz.albe@wien.gv.at> wrote:
>
> > The execution plan of dynamic queries from PL/pgSQL will not be
> > cached; the query will be prepared at execution time every time you
> > execute it.

>
> Pardon my ignorance but I really have a very vague idea of what the
> planner does and how it works.
>
> Does the planner "compose" plans or does it have one plan for each
> statement?


The planner takes a query and creates a plan. Later, the executor takes
a plan and executes it, producing results. For example you can create
plans with the PREPARE command, and later execute them with the EXECUTE
command (note that the EXECUTE SQL command is different from the EXECUTE
plpgsql command).

PL/pgSQL can present a query to the planner, and get a plan. This plan
can be cached by PL/pgSQL. So if you execute a function twice, the
first time PL/pgSQL caches the plan and passes it to the executor; the
second time PL/pgSQL gets the plan from the cache and passes it to the
executor.

Except if you use plpgsql's EXECUTE: when you do that, PL/pgSQL does no
caching at all for that query, and asks the planner for a new plan each
time.

Also, new in 8.3 is a facility for "plan invalidation", which means that
every time the server executes something that makes that plan stale, the
cache is dropped and the plan is rebuilt next time.

--
Alvaro Herrera http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.

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

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #4 (permalink)  
Old 04-10-2008, 12:22 AM
Ivan Sergio Borgonovo
 
Posts: n/a
Default Re: dynamically generated SQL and planner/performance

On Sat, 22 Mar 2008 14:56:28 -0300
Alvaro Herrera <alvherre@commandprompt.com> wrote:


> PL/pgSQL can present a query to the planner, and get a plan. This
> plan can be cached by PL/pgSQL. So if you execute a function
> twice, the first time PL/pgSQL caches the plan and passes it to the
> executor; the second time PL/pgSQL gets the plan from the cache and
> passes it to the executor.
>
> Except if you use plpgsql's EXECUTE: when you do that, PL/pgSQL
> does no caching at all for that query, and asks the planner for a
> new plan each time.


But does this cascade to all the nested functions?

functionA {
execute functionB {
sql statement
}
}

As my previous example I've a functionA that build up a statement that
call another functionB that just contain static sql statements.

Will the plan for the statements inside functionB be used if it is
called indirectly?

So the loss will depends only on how complicated is the statement
that get "execute"d.

If it's something like
execute select res fron functionB() into _res;
since the "complicated" part is inside each functionB I shouldn't
expect any great loss.

Is it?

thanks

--
Ivan Sergio Borgonovo
http://www.webthatworks.it


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

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #5 (permalink)  
Old 04-10-2008, 12:22 AM
Alvaro Herrera
 
Posts: n/a
Default Re: dynamically generated SQL and planner/performance

Ivan Sergio Borgonovo wrote:

> But does this cascade to all the nested functions?
>
> functionA {
> execute functionB {
> sql statement
> }
> }
>
> As my previous example I've a functionA that build up a statement that
> call another functionB that just contain static sql statements.


Each function is planned and cached independently, regardless of how
they are called. In fact the previous sentence does not really make
sense, because what truly happens is that each _sentence_ within each
function is planned and cached independently.


> If it's something like
> execute select res fron functionB() into _res;
> since the "complicated" part is inside each functionB I shouldn't
> expect any great loss.
>
> Is it?


Correct -- the part that's being discarded each time here is the SELECT
that calls up functionB, not functionB's statements themselves.

--
Alvaro Herrera http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.

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

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 10:19 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
www.UnixAdminTalk.com