Re: Queries with large ResultSets
Re: Queries with large ResultSets
От:
Dave Cramer <pg@fastcrypt.com>
Дата:
You can use a holdable cursor, and get a cursor outside of a transaction, but beware, postgres has to store this somewhere, and it's not update-able Dave On Thu, 2004-05-20 at 15:27, Andrea Aime wrote: > Alle 20:44, giovedì 20 maggio 2004, Tom Lane ha scritto: > > Andrea Aime writes: > > > Ugh... those limitation are really frightening, this means we cannot > > > fetch big quantities of data outside of a transaction... > > > > You were expecting something different? Postgres does not do *anything* > > outside of a transaction. > > Every other database I have some experience on (sql server, sapdb) allows you > to use cursors regardless of the transaction. If you are working with a > database in autocommit mode that doesn't mean that you don't need to load > huge quantities of data... on the contrary, I would expect that it would be > more costly to load the huge amount of data inside of a transaction because > of transaction isolation. > Anyway, that's not the matter, the real problem is that our generic jdbc code > won't work properly with postgres because of this "feature" thus we will have > to subclass everything that deals with the database in order to get the > correct behaviour. > > If I am in autocommit = false mode, I will have to call connection.commit() > after every write command to the database... isolation wise, to simulate a > true autocommit, will I have to call connection.commit() also after reads if > I raise the isolation level above READ_COMMITED? > > Best regards > Andrea Aime > > > ---------------------------(end of broadcast)--------------------------- > TIP 6: Have you searched our list archives? > > http://archives.postgresql.org > > > > !DSPAM:40ad082858103601796679! > > -- Dave Cramer 519 939 0336 ICQ # 14675561
Re: Queries with large ResultSets
От:
Dave Cramer <pg@fastcrypt.com>
Дата:
There's some confusion as to whether a cursor is materialized even
inside a transaction. It could be that complicated queries will be
stored on the disk too.
Tom ?
Dave
On Thu, 2004-05-20 at 18:54, Oliver Jowett wrote:
> Andrea Aime wrote:
>
> > Ugh... those limitation are really frightening, this means we cannot fetch
> > big quantities of data outside of a transaction... this is a problem with
> > application servers like GeoServer that keep a connection pool and
> > need to fetch big quantities of data also outside a transaction... any hope
> > to see this fixed soon? Is it a driver problem or a server limitation?
>
> Cursor are implicitly closed at the end of a transaction unless they are
> declared WITH HOLD. Declaring a cursor WITH HOLD has an associated cost
> on the backend (namely it will copy the cursor's contents at the end of
> the transaction). If autocommit is on, you have an implicit transaction
> around every query, so it doesn't make sense to use a non-holdable
> cursor with autocommit on -- you'd never be able to fetch any results.
>
> This could be controllable via the JDBC3 resultset holdability methods,
> but currently it isn't and all resultsets effectively default to
> ResultSet.CLOSE_CURSORS_AT_COMMIT.
>
> I don't think you want a holdable cursor for this case anyway since the
> backend would end up doing a lot of unnecessary copying results around.
> If you're accessing big quantities of data, the overhead of an explicit
> commit() after you're done with the resultset is going to be
> insignificant compared to the cost of actually transferring and handling
> that data. Use something like this:
>
> connection.setAutoCommit(false);
> PreparedStatement stmt = connection.prepareStatement("SELECT ....");
> ResultSet rs = stmt.executeQuery();
> while (rs.next()) {
> // process data
> }
> rs.close();
> connection.commit();
>
> -O
>
> ---------------------------(end of broadcast)---------------------------
> TIP 9: the planner will ignore your desire to choose an index scan if your
> joining column's datatypes do not match
>
>
>
> !DSPAM:40ad3936130991925076984!
>
>
--
Dave Cramer
519 939 0336
ICQ # 14675561
Re: Queries with large ResultSets
От:
Andrea Aime <andrea.aime@aliceposta.it>
Дата:
Alle 18:01, giovedì 20 maggio 2004, Kris Jurka ha scritto: > On Wed, 19 May 2004, Jack Orenstein wrote: > > If I'm reading the source code correctly, the PostgreSQL 7.3.4 JDBC > > driver creates a ResultSet by evaluating the entire query, and putting > > all the rows into a Vector. ResultSet.next() iterates over the > > Vector. Is that in fact what is happening? > > Yes, in the 7.3 driver. The 7.4 driver (which works quite well against a > 7.3 database) will use a cursor based fetch to retrieve a chunk of rows at > a time. There are a number of restrictions required to be able to use > this method (It only works with autocommit off and FORWARD_ONLY result > sets). To enable this use Statement.setFetchSize to indicate how many > rows at a time you want retrieved. Also there is a patch to the 7.5 > driver to be able to retrieve subsets of the resultset for the scrollable > variety and hopefully I should get that in soon. Ugh... those limitation are really frightening, this means we cannot fetch big quantities of data outside of a transaction... this is a problem with application servers like GeoServer that keep a connection pool and need to fetch big quantities of data also outside a transaction... any hope to see this fixed soon? Is it a driver problem or a server limitation? Best regards Andrea Aime
Re: Queries with large ResultSets
От:
Andrea Aime <andrea.aime@aliceposta.it>
Дата:
Alle 20:44, giovedì 20 maggio 2004, Tom Lane ha scritto: > Andrea Aime writes: > > Ugh... those limitation are really frightening, this means we cannot > > fetch big quantities of data outside of a transaction... > > You were expecting something different? Postgres does not do *anything* > outside of a transaction. Every other database I have some experience on (sql server, sapdb) allows you to use cursors regardless of the transaction. If you are working with a database in autocommit mode that doesn't mean that you don't need to load huge quantities of data... on the contrary, I would expect that it would be more costly to load the huge amount of data inside of a transaction because of transaction isolation. Anyway, that's not the matter, the real problem is that our generic jdbc code won't work properly with postgres because of this "feature" thus we will have to subclass everything that deals with the database in order to get the correct behaviour. If I am in autocommit = false mode, I will have to call connection.commit() after every write command to the database... isolation wise, to simulate a true autocommit, will I have to call connection.commit() also after reads if I raise the isolation level above READ_COMMITED? Best regards Andrea Aime
Re: Queries with large ResultSets
От:
Andrea Aime <andrea.aime@aliceposta.it>
Дата:
Alle 22:03, giovedì 20 maggio 2004, Dave Cramer ha scritto: > You can use a holdable cursor, and get a cursor outside of a > transaction, but beware, postgres has to store this somewhere, and it's > not update-able Store it somewhere means that it has to write the result of the query to persistent storage and then provide scrolling over it? It's not the best way to do things since in the case of geoserver the query result can be several megabytes (gis data)... Anyway, how do I get such a cursor using the JDBC driver? Moreover, would the hack of calling commit() at the end of every operation in order to simulate an autocommit connection work? Best regards Andrea Aime
Re: Queries with large ResultSets
От:
Andrea Aime <andrea.aime@aliceposta.it>
Дата:
Alle 00:54, venerdì 21 maggio 2004, Oliver Jowett ha scritto:
> Andrea Aime wrote:
...
> I don't think you want a holdable cursor for this case anyway since the
> backend would end up doing a lot of unnecessary copying results around.
> If you're accessing big quantities of data, the overhead of an explicit
> commit() after you're done with the resultset is going to be
> insignificant compared to the cost of actually transferring and handling
> that data. Use something like this:
>
> connection.setAutoCommit(false);
> PreparedStatement stmt = connection.prepareStatement("SELECT ....");
> ResultSet rs = stmt.executeQuery();
> while (rs.next()) {
> // process data
> }
> rs.close();
> connection.commit();
>
> -O
I see... well, that's what I will need to do it seems. Thank you for the
advice :-)
Best regards
Andrea Aime
Re: Queries with large ResultSets
От:
Tom Lane <tgl@sss.pgh.pa.us>
Дата:
Dave Cramer writes: > There's some confusion as to whether a cursor is materialized even > inside a transaction. It could be that complicated queries will be > stored on the disk too. It depends on the query and on the cursor options. If you don't say SCROLL nor WITH HOLD then the result isn't materialized anywhere, it's just computed and delivered incrementally in response to FETCH commands. If you specify SCROLL and the query plan isn't one that's amenable to being run backwards, then we materialize the result (ie, save aside each row the first time it is read from the underlying query) so that we can support FETCH BACKWARD. By and large, only the simplest seqscan or indexscan plans (no joins, aggregates, etc) are capable of being run backwards and so can handle SCROLL without overhead. You can use "EXPLAIN DECLARE CURSOR" to see whether a particular query can do this --- look at whether a Materialize node gets stuck atop the plan when you add SCROLL. If you specify WITH HOLD and don't close the cursor before transaction end, then at transaction end the result is materialized: we read the entire query output (including any rows you already read) and save it aside to support future FETCHes. regards, tom lane
Re: Queries with large ResultSets
От:
Tom Lane <tgl@sss.pgh.pa.us>
Дата:
Andrea Aime writes: > Ugh... those limitation are really frightening, this means we cannot fetch > big quantities of data outside of a transaction... You were expecting something different? Postgres does not do *anything* outside of a transaction. regards, tom lane
Re: Queries with large ResultSets
От:
Oliver Jowett <oliver@opencloud.com>
Дата:
Andrea Aime wrote:
> Ugh... those limitation are really frightening, this means we cannot fetch
> big quantities of data outside of a transaction... this is a problem with
> application servers like GeoServer that keep a connection pool and
> need to fetch big quantities of data also outside a transaction... any hope
> to see this fixed soon? Is it a driver problem or a server limitation?
Cursor are implicitly closed at the end of a transaction unless they are
declared WITH HOLD. Declaring a cursor WITH HOLD has an associated cost
on the backend (namely it will copy the cursor's contents at the end of
the transaction). If autocommit is on, you have an implicit transaction
around every query, so it doesn't make sense to use a non-holdable
cursor with autocommit on -- you'd never be able to fetch any results.
This could be controllable via the JDBC3 resultset holdability methods,
but currently it isn't and all resultsets effectively default to
ResultSet.CLOSE_CURSORS_AT_COMMIT.
I don't think you want a holdable cursor for this case anyway since the
backend would end up doing a lot of unnecessary copying results around.
If you're accessing big quantities of data, the overhead of an explicit
commit() after you're done with the resultset is going to be
insignificant compared to the cost of actually transferring and handling
that data. Use something like this:
connection.setAutoCommit(false);
PreparedStatement stmt = connection.prepareStatement("SELECT ....");
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
// process data
}
rs.close();
connection.commit();
-O
Re: Queries with large ResultSets
От:
Oliver Jowett <oliver@opencloud.com>
Дата:
Dave Cramer wrote: > There's some confusion as to whether a cursor is materialized even > inside a transaction. It could be that complicated queries will be > stored on the disk too. The docs cover this. Executive summary: SCROLL cursors might be more expensive than NO SCROLL cursors, depending on the query. It's a separate issue to WITH HOLD / WITHOUT HOLD as far as I know. http://www.postgresql.org/docs/7.4/static/sql-declare.html -O
Re: Queries with large ResultSets
От:
Kris Jurka <books@ejurka.com>
Дата:
On Wed, 19 May 2004, Jack Orenstein wrote: > If I'm reading the source code correctly, the PostgreSQL 7.3.4 JDBC > driver creates a ResultSet by evaluating the entire query, and putting > all the rows into a Vector. ResultSet.next() iterates over the > Vector. Is that in fact what is happening? > Yes, in the 7.3 driver. The 7.4 driver (which works quite well against a 7.3 database) will use a cursor based fetch to retrieve a chunk of rows at a time. There are a number of restrictions required to be able to use this method (It only works with autocommit off and FORWARD_ONLY result sets). To enable this use Statement.setFetchSize to indicate how many rows at a time you want retrieved. Also there is a patch to the 7.5 driver to be able to retrieve subsets of the resultset for the scrollable variety and hopefully I should get that in soon. Kris Jurka