Search Postgresql Archives

Re: Difference between speed of 2 functions: SQL+STABLE and PLPGSQL+EXECUTE

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

 



Dmitry Koterov wrote:
> But it's quite strange that SQL+STABLE function does not recalculate
the plan each time it is called.
> Because when I use a bunch of SQL+STABLE functions in e.g. a
sub-select of a complex query, I see in
> the plan of this complex queries that function calls are "expanded".
It looks like PostgreSQL uses SQL
> code defined in SQL+STABLE functions and merges (injects) it into the
main query instead of the
> function call.
> 
> E.g.:
> 
>
========================================================================
==
> CREATE TABLE a(i INTEGER, t VARCHAR(5));
> INSERT INTO a(i, t) SELECT s, '' FROM generate_series(1, 10000) s;
> INSERT INTO a(i, t) SELECT s, 't' FROM generate_series(10001, 10002)
s;
> CREATE INDEX "a_i_idx" ON "public"."a" USING btree ("i");
> CREATE INDEX "a_t_idx" ON "public"."a" USING btree ("t");
> ANALYZE a;
> 
> CREATE OR REPLACE FUNCTION a_get_t(in_a a) RETURNS TEXT STABLE
LANGUAGE sql
> AS 'SELECT $1.t';
> 
> explain analyze
> select * from a
> where a_get_t(a) = 't';
> 
> QUERY PLAN
> Index Scan using a_t_idx on a  (cost=0.00..8.29 rows=2 width=5)
(actual time=0.041..0.043 rows=2
> loops=1)
>   Index Cond: ((t)::text = 't'::text)
>
========================================================================
==
> 
> You may see that a_get_t() SQL code was merged into the main query
plan, so the result is found
> without a seqscan with t='t' filtering, but the index is used.
> 
> That was a very simple example, I use much more complex SQL+STABLE
functions in my code and I am
> practically sure that this SQL extraction+injection is applied by
PostgreSQL in other cases too (e.g.
> sometimes planner initiates a hash join with tables which are referred
inside SQL+STABLE functions in
> sub-queries). If I replace STABLE with VOLATILE in that complex cases,
the effect disappears: no more
> SQL extraction performed.
> 
> And more: assume we have a function f(x, y, z) VOLATILE with very
complex SQL inside and we call it
> like:
> 
> select * from f(1, 2, 3);
> 
> The query may took a long time (during not only the first call, but
during all others too). Then I
> just replace VOLATILE to STABLE for f(), and the same query:
> 
> select * from f(1, 2, 3);
> 
> suddenly becomes very fast (e.g. 1000 times faster or even more). It's
a very common case: I've
> performed many times. I thought that it was because of re-planning of
STABLE functions on each call
> according to real passed values...
> 
> If STABLE functions has frozen plans too (independent to its real
passed arguments values), how could
> we explain so much difference in performance replacing VOLATILE to
STABLE?

Simple SQL functions can get "inlined" in queries by the planner,
that's what you see in your first example.

This is IMO unrelated to the problem you describe where a complicated
STABLE SQL function performs much better than the same function declared
VOLATILE.

To understand that difference, one would have to look at the function
definition and EXPLAIN output for both cases, possibly using
auto_analyze.

Yours,
Laurenz Albe



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



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Postgresql Jobs]     [Postgresql Admin]     [Postgresql Performance]     [Linux Clusters]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Postgresql & PHP]     [Yosemite]
  Powered by Linux