Talk About Network

Google


Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Data Bases > Pgsql Performance > Re: Cached Quer...
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 1 of 1 Topic 3989 of 4345
Post > Topic >>

Re: Cached Query Plans

by lists@[EMAIL PROTECTED] (PFC) Apr 12, 2008 at 11:13 AM

> Well if you're caching per-connection then it doesn't really matter=20=20
> whether
> you do it on the client side or the server side, it's pretty much=20=20
> exactly the
> same problem.

	Actually I thought about doing it on the server since it would then also=
=20=20
work with connection pooling.
	Doing it on the client means the client has to maintain state, which
is=20=
=20
not possible in a pool...

> Unsurprisingly most drivers do precisely what you're describing. In
Perl=
=20=20
> DBI
> for example you just change $dbh->prepare("") into=20=20
> $dbh->prepare_cached("")
> and it does exactly what you want. I would expect the PHP drivers to
have
> something equivalent.

	Well, PHP doesn't.
	Perhaps I should patch PHP instead...
	Or perhaps this feature should be implemented in pgpool or pgbouncer.

>> 	But, using prepared statements with persistent connections is
messy,=20=
=20
>> because you never know if the connection is new or not,

> If you were to fix *that* then both this problem and others (such as
> setting up desired SET-parameter values) would go away.=09

	True. Languages that keep a long-running context (like application=20=20
servers etc) can do this easily.
	Although in the newer versions of PHP, it's not so bad, pconnect seems
to=
=20=20
work (ie. it will issue ROLLBACKs when the script dies, reset
session=20=20
variables like enable_indexscan, etc), so the only remaining problem
seems=
=20=20
to be prepared statements.
	And again, adding a method for the application to know if the persistent=
=20=20
connection is new or not, will not work in a connection pool...

	Perhaps a GUC flag saying EXECUTE should raise an error but not kill the=
=20=20
current transaction if the requested prepared statement does not exist
?=20=
=20
Then the application would issue a PREPARE. It could also raise a=20=20
non-fatal error when the tables have changed (column added, for instance)=
=20=20
so the application can re-issue a PREPARE.

	But I still think it would be cleaner to do it in the server.

	Also, I rethought about what Gregory Stark said :
> The contention on the shared cache is likely to negate much of the=20=20
> planning
> savings but I think it would still be a win.

	If a shared plan cache is implemented, it will mostly be read-only,
ie.=20=
=20
when the application is started, new queries will come, so the plans will=
=20=20
have to be written to the cache, but then once the cache contains=20=20
everything it needs, it will not be modified that often, so I wouldn't=20=
=20
think contention would be such a problem...

> It's not so easy as all that.  Consider search_path.  Consider temp
> tables.

	Temp tables : I thought plan revalidation took care of this ?
	(After testing, it does work, if a temp table is dropped and
recreated,=20=
=20
PG finds it, although of course if a table is altered by adding a
column=20=
=20
for instance, it logically fails).

	search_path: I suggested to either put the search_path in the cache
key=20=
=20
along with the SQL string, or force queries to specify schema.table
for=20=
=20
all tables.
	It is also possible to shoot one's foot with the current PREPARE (ie.=20=
=20
search_path is used to PREPARE but of course not for EXECUTE), and
also=20=
=20
with plpgsql functions (ie. the search path used to compile the
function=20=
=20
is the one that is active when it is compiled, ie at its first call in
the=
=20=20
current connection, and not the search path that was active when the=20=20
function was defined)...

SET search_path TO DEFAULT;

CREATE SCHEMA a;
CREATE SCHEMA b;

CREATE TABLE a.test( v TEXT );
CREATE TABLE b.test( v TEXT );

INSERT INTO a.test VALUES ('This is schema a');
INSERT INTO b.test VALUES ('This is schema b');

CREATE OR REPLACE FUNCTION test_search_path()
     RETURNS SETOF TEXT
     LANGUAGE plpgsql
     AS
$$
DECLARE
     x TEXT;
BEGIN
     FOR x IN SELECT v FROM test LOOP
         RETURN NEXT x;
     END LOOP;
END;
$$;

test=3D> SET search_path TO a,public;
test=3D> SELECT * FROM test_search_path();
  test_search_path
------------------
  This is schema a
test=3D> \q
$ psql test

test=3D> SET search_path TO b,public;
test=3D> SELECT * FROM test_search_path();
  test_search_path
------------------
  This is schema b

test=3D> SET search_path TO a,public;
test=3D> SELECT * FROM test_search_path();
  test_search_path
------------------
  This is schema b






--=20
Sent via pgsql-performance mailing list (pgsql-performance@[EMAIL PROTECTED]
)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance
 




 1 Posts in Topic:
Re: Cached Query Plans
lists@[EMAIL PROTECTED]   2008-04-12 11:13:46 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Mon Oct 6 15:41:03 CDT 2008.