Reusing cached prepared statement slow after 5 executions

Started by Rob Gansevlesalmost 15 years ago7 messagesgeneral
Jump to latest
#1Rob Gansevles
rgansevles@gmail.com

Hi,

I came across a strange issue when caching prepared statement..

We are accessing postgres(9.0.3) via the jdbc driver (9.0b801) using a
prepared statement cache.
This works very good but in 1 case the 5th execution (and later ones)
suddenly takes 30 seconds as the first few just take less then 1 sec.

When I disable prepared statement caching all executions are fast.

The query is:

select 1 from asiento left outer join asiento_cab
on asiento.asiento_cab_id=asiento_cab.asiento_cab_id where asiento_cab.anio = ?
and asiento_cab.mes between ? and ?
and asiento.aux_cuenta between ? and ?
and asiento.hija = ?

Each execution has the same input parameters.

When I remove any of the conditions in the query, all executions are
of the same speed.

Has anyone seen this behaviour before?

When the slow query runs, i see a 100% cpu usage of the postgres
process, so I guess this would be an issue with the engine.
But I can only reproduce this with the jdbc driver and reuse a
prepared statement.
So when filing a bug, against what should be bug be filed, the engine
or the driver?

Thanks for any comments,

Rob

PS (sorry about my prev email, it got sent incomplete)

#2David G. Johnston
david.g.johnston@gmail.com
In reply to: Rob Gansevles (#1)
Re: Reusing cached prepared statement slow after 5 executions

This is likely the case where the first few "prepared statements" are not truly prepared. Once you hit five the cache kicks in and computes a generic query plan to cache. Since this plan is generic, where the first five were specific, it exhibits worse performance than queries where the where clause is known.

It's isn't a bug but you should see if you can get psql to reproduce the behavior by manually issuing a prepare. If you can do so you remove JDBC from the equation and make testing much easier.

You could also just rewrite the query to give the query planner a hand.

David J.

On Jun 26, 2011, at 10:52, Rob Gansevles <rgansevles@gmail.com> wrote:

Show quoted text

Hi,

I came across a strange issue when caching prepared statement..

We are accessing postgres(9.0.3) via the jdbc driver (9.0b801) using a
prepared statement cache.
This works very good but in 1 case the 5th execution (and later ones)
suddenly takes 30 seconds as the first few just take less then 1 sec.

When I disable prepared statement caching all executions are fast.

The query is:

select 1 from asiento left outer join asiento_cab
on asiento.asiento_cab_id=asiento_cab.asiento_cab_id where asiento_cab.anio = ?
and asiento_cab.mes between ? and ?
and asiento.aux_cuenta between ? and ?
and asiento.hija = ?

Each execution has the same input parameters.

When I remove any of the conditions in the query, all executions are
of the same speed.

Has anyone seen this behaviour before?

When the slow query runs, i see a 100% cpu usage of the postgres
process, so I guess this would be an issue with the engine.
But I can only reproduce this with the jdbc driver and reuse a
prepared statement.
So when filing a bug, against what should be bug be filed, the engine
or the driver?

Thanks for any comments,

Rob

PS (sorry about my prev email, it got sent incomplete)

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

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: David G. Johnston (#2)
Re: Reusing cached prepared statement slow after 5 executions

David Johnston <polobo@yahoo.com> writes:

This is likely the case where the first few "prepared statements" are
not truly prepared. Once you hit five the cache kicks in and computes
a generic query plan to cache.

Not so much that as that JDBC decides that it should tell the backend to
start using a prepared plan. See the JDBC docs.

regards, tom lane

#4Rob Gansevles
rgansevles@gmail.com
In reply to: Tom Lane (#3)
Re: Reusing cached prepared statement slow after 5 executions

I can confirm, when I call ps.setPrepareThreshold(1) the query is slow
immediately, so the plan must be different with the server prepared
statements.

Thanks,

Rob

Show quoted text

On Sun, Jun 26, 2011 at 5:11 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

David Johnston <polobo@yahoo.com> writes:

This is likely the case where the first few "prepared statements" are
not truly prepared.  Once you hit five the cache kicks in and computes
a generic query plan to cache.

Not so much that as that JDBC decides that it should tell the backend to
start using a prepared plan.  See the JDBC docs.

                       regards, tom lane

#5Dean Rasheed
dean.a.rasheed@gmail.com
In reply to: Rob Gansevles (#4)
Re: Reusing cached prepared statement slow after 5 executions

On 27 June 2011 07:50, Rob Gansevles <rgansevles@gmail.com> wrote:

I can confirm, when I call ps.setPrepareThreshold(1) the query is slow
immediately, so the plan must be different with the server prepared
statements.

You can confirm that from psql by doing

EXPLAIN ANALYSE SELECT ... ;

and then

PREPARE ps( ... ) AS SELECT ... ;
EXPLAIN ANALYSE EXECUTE ps ( ... ) ;

using your query and the parameters in question.

It is entirely possible that the plan chosen for the prepared
statement will be worse than the one used when the parameters are
known at planning time. The prepared statement doesn't know what
parameters are going to be used, so it can't always come up with the
best plan. See the notes in the PREPARE manual page:
http://www.postgresql.org/docs/9.0/static/sql-prepare.html

Regards,
Dean

#6Laurenz Albe
laurenz.albe@cybertec.at
In reply to: Dean Rasheed (#5)
Re: Reusing cached prepared statement slow after 5 executions

Dean Rasheed wrote:

I can confirm, when I call ps.setPrepareThreshold(1) the query is

slow

immediately, so the plan must be different with the server prepared
statements.

You can confirm that from psql by doing

EXPLAIN ANALYSE SELECT ... ;

and then

PREPARE ps( ... ) AS SELECT ... ;
EXPLAIN ANALYSE EXECUTE ps ( ... ) ;

using your query and the parameters in question.

It is entirely possible that the plan chosen for the prepared
statement will be worse than the one used when the parameters are
known at planning time. The prepared statement doesn't know what
parameters are going to be used, so it can't always come up with the
best plan. See the notes in the PREPARE manual page:
http://www.postgresql.org/docs/9.0/static/sql-prepare.html

Could the parameter cursor_tuple_fraction play a role here too?

Yours,
Laurenz Albe

#7Radosław Smogura
rsmogura@softperience.eu
In reply to: Laurenz Albe (#6)
Re: Reusing cached prepared statement slow after 5 executions

This behavior is in some way needed, as PreparedStatement is, commonly, used once, just to pass parameters without escaping.

Regards,
Radek

-----Original Message-----
From: Rob Gansevles
Sent: 27 czerwca 2011 08:50
To: pgsql-general
Subject: Re: [GENERAL] Reusing cached prepared statement slow after 5 executions

I can confirm, when I call ps.setPrepareThreshold(1) the query is slow
immediately, so the plan must be different with the server prepared
statements.

Thanks,

Rob

On Sun, Jun 26, 2011 at 5:11 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

David Johnston <polobo@yahoo.com> writes:

This is likely the case where the first few "prepared statements" are
not truly prepared.  Once you hit five the cache kicks in and computes
a generic query plan to cache.

Not so much that as that JDBC decides that it should tell the backend to
start using a prepared plan.  See the JDBC docs.

                       regards, tom lane

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