Re: function(contants) evaluated for every row

Lists: pgsql-hackers
From: Bruce Momjian <bruce(at)momjian(dot)us>
To: PostgreSQL-development <pgsql-hackers(at)postgreSQL(dot)org>
Subject: function(contants) evaluated for every row
Date: 2010-11-24 19:36:08
Message-ID: 201011241936.oAOJa8h04792@momjian.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Someone offlist reported query slowness because we don't convert
function calls with all-constant parameters to be a constants before we
start a sequential scan:

EXPLAIN SELECT * FROM test WHERE
x >= to_date('2001-01-01', 'YYYY-MM-DD') AND
x <= to_date('2001-01-01', 'YYYY-MM-DD');

QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------

Seq Scan on test (cost=0.00..58.00 rows=12 width=4)
Filter: ((x >= to_date('2001-01-01'::text, 'YYYY-MM-DD'::text)) AND
(x <= to_date('2001-01-01'::text, 'YYYY-MM-DD'::text)))
(2 rows)

Notice the to_date()'s were not converted to constants in EXPLAIN so
they are evaluated for every row. to_date() is marked STABLE.

Is this something we should improve?

--
Bruce Momjian <bruce(at)momjian(dot)us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ It's impossible for everything to be true. +


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Bruce Momjian <bruce(at)momjian(dot)us>
Cc: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: function(contants) evaluated for every row
Date: 2010-11-24 19:52:22
Message-ID: 16830.1290628342@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Bruce Momjian <bruce(at)momjian(dot)us> writes:
> Notice the to_date()'s were not converted to constants in EXPLAIN so
> they are evaluated for every row. to_date() is marked STABLE.

> Is this something we should improve?

No. This is per expectation. Only IMMUTABLE functions can be folded to
constants in advance of the query.

regards, tom lane


From: Bruce Momjian <bruce(at)momjian(dot)us>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: function(contants) evaluated for every row
Date: 2010-11-24 19:57:53
Message-ID: 201011241957.oAOJvro06363@momjian.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Tom Lane wrote:
> Bruce Momjian <bruce(at)momjian(dot)us> writes:
> > Notice the to_date()'s were not converted to constants in EXPLAIN so
> > they are evaluated for every row. to_date() is marked STABLE.
>
> > Is this something we should improve?
>
> No. This is per expectation. Only IMMUTABLE functions can be folded to
> constants in advance of the query.

Well CREATE FUNCTION says about STABLE:

STABLE indicates that the function cannot modify the
database, and that within a single table scan it will
consistently return the same result for the same
argument values, but that its result could change
across SQL statements. This is the appropriate
selection for functions whose results depend on
database lookups, parameter variables (such as the
current time zone), etc. (It is inappropriate for
AFTER triggers that wish to query rows modified by the
current command.) Also note that the current_timestamp
family of functions qualify as stable, since their
values do not change within a transaction.

I realize they can't be converted to constants before the query starts
but is there a reason we can't convert those functions to constants in
the executor before a table scan?

--
Bruce Momjian <bruce(at)momjian(dot)us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ It's impossible for everything to be true. +


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Bruce Momjian <bruce(at)momjian(dot)us>
Cc: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: function(contants) evaluated for every row
Date: 2010-11-24 20:19:14
Message-ID: 18279.1290629954@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Bruce Momjian <bruce(at)momjian(dot)us> writes:
> I realize they can't be converted to constants before the query starts
> but is there a reason we can't convert those functions to constants in
> the executor before a table scan?

Other than the significant number of cycles that would be wasted (in
most cases) checking for the possibility, probably not. I'm dubious
that it would average out to a win though.

regards, tom lane


From: Marti Raudsepp <marti(at)juffo(dot)org>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Bruce Momjian <bruce(at)momjian(dot)us>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: function(contants) evaluated for every row
Date: 2010-11-24 20:28:49
Message-ID: AANLkTikACkchLRvOZxJSP7_xxKZ29o4isy95NvNm7-0i@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On Wed, Nov 24, 2010 at 21:52, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
> Bruce Momjian <bruce(at)momjian(dot)us> writes:
>> Notice the to_date()'s were not converted to constants in EXPLAIN so
>> they are evaluated for every row.  to_date() is marked STABLE.

> No.  This is per expectation.  Only IMMUTABLE functions can be folded to
> constants in advance of the query.

This is something that has bit me in the past.

I realize that STABLE functions cannot be constant-folded at
planning-time. But are there good reasons why it cannot called only
once at execution-time?

As long as *only* STABLE or IMMUTABLE functions are used in a query,
we can assume that settings like timezone won't change in the middle
of the execution of a function, thus STABLE function calls can be
collapsed -- right?

Regards,
Marti


From: Michael Glaesemann <grzm(at)seespotcode(dot)net>
To: Marti Raudsepp <marti(at)juffo(dot)org>
Cc: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Bruce Momjian <bruce(at)momjian(dot)us>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: function(contants) evaluated for every row
Date: 2010-11-25 00:20:37
Message-ID: E05E70E4-721E-4A3A-8DEC-7FF9ADA5A74E@seespotcode.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers


On Nov 24, 2010, at 15:28 , Marti Raudsepp wrote:

> On Wed, Nov 24, 2010 at 21:52, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
>> Bruce Momjian <bruce(at)momjian(dot)us> writes:
>>> Notice the to_date()'s were not converted to constants in EXPLAIN so
>>> they are evaluated for every row. to_date() is marked STABLE.
>
>> No. This is per expectation. Only IMMUTABLE functions can be folded to
>> constants in advance of the query.
>
> This is something that has bit me in the past.
>
> I realize that STABLE functions cannot be constant-folded at
> planning-time. But are there good reasons why it cannot called only
> once at execution-time?
>
> As long as *only* STABLE or IMMUTABLE functions are used in a query,
> we can assume that settings like timezone won't change in the middle
> of the execution of a function, thus STABLE function calls can be
> collapsed -- right?

I've seen this as well be a performance issue, in particular with partitioned tables. Out of habit I now write functions that always cache the value of the function in a variable and use the variable in the actual query to avoid this particular "gotcha".

Michael Glaesemann
grzm seespotcode net