Re: Can you please tell us how set this prefetch attribute in following lines.

From: Laurenz Albe <laurenz(dot)albe(at)cybertec(dot)at>
To: M Tarkeshwar Rao <m(dot)tarkeshwar(dot)rao(at)ericsson(dot)com>, "pgsql-general(at)postgresql(dot)org" <pgsql-general(at)postgresql(dot)org>
Subject: Re: Can you please tell us how set this prefetch attribute in following lines.
Date: 2019-10-17 17:05:57
Message-ID: 94767a9a3fed70059881bd60f33ad5971099213f.camel@cybertec.at
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general pgsql-hackers pgsql-performance

On Thu, 2019-10-17 at 11:16 +0000, M Tarkeshwar Rao wrote:
> How to fetch certain number of tuples from a postgres table.
>
> Same I am doing in oracle using following lines by setting prefetch attribute.
>
> For oracle
> // Prepare query
> if( OCIStmtPrepare( myOciStatement, myOciError, (text *)aSqlStatement,
> // Get statement type
> OCIAttrGet( (void *)myOciStatement, OCI_HTYPE_STMT, &statement_type, 0, OCI_ATTR_STMT_TYPE, myOciError );
> // Set prefetch count
> OCIAttrSet( myOciStatement, OCI_HTYPE_STMT, &prefetch, 0, OCI_ATTR_PREFETCH_ROWS, myOciError );
> // Execute query
> status = OCIStmtExecute( myOciServerCtx, myOciStatement, myOciError, iters, 0, NULL, NULL, OCI_DEFAULT );
>
> For Postgres
>
> Can you please tell us how set this prefetch attribute in following lines. Is PQexec returns all the rows from the table?
>
> mySqlResultsPG = PQexec(connection, aSqlStatement);
>
> if((PQresultStatus(mySqlResultsPG) == PGRES_FATAL_ERROR ) || (PQstatus(connection) != CONNECTION_OK)){}
> if ((PQresultStatus(mySqlResultsPG) == PGRES_COMMAND_OK) || (PQresultStatus(mySqlResultsPG) == PGRES_TUPLES_OK))
> {
> myNumColumns = PQnfields(mySqlResultsPG);
> myTotalNumberOfRowsInQueryResult = PQntuples(mySqlResultsPG);
> myCurrentRowNum = 0 ;
> }

The C API doesn't offer anything like Oracle prefetch to force prefetching of a certain
number of result rows.

In the PostgreSQL code you show above, the whole result set will be fetched in one go
and cached in client RAM, so in a way you have "prefetch all".

The alternative thet the C API gives you is PQsetSingleRowMode(), which, when called,
will return the result rows one by one, as they arrive from the server.
That disables prefetching.

If you want to prefetch only a certain number of rows, you can use the DECLARE and
FETCH SQL statements to create a cursor in SQL and fetch it in batches.

This workaround has the down side that the current query shown in "pg_stat_activity"
or "pg_stat_statements" is always something like "FETCH 32", and you are left to guess
which statement actually caused the problem.

If you are willing to bypass the C API and directly speak the network protocol with
the server, you can do better. This is documented in
https://www.postgresql.org/docs/current/protocol.html

The "Execute" ('E') message allows you to send an integer with the maximum number of
rows to return (0 means everything), so that does exactly what you want.

The backend will send a "PortalSuspended" ('s') to indicate that there is more to come,
and you keep sending "Execute" until you get a "CommandComplete" ('C').

I you feel hacky you could write C API support for that...

If you use that or a cursor, PostgreSQL will know that you are executing a cursor
and will plan its queries differently: it will assume that only "cursor_tuple_fraction"
(default 0.1) of your result set is actually fetched and prefer fast startup plans.
If you don't want that, because you are fetching batches as fast as you can without
lengthy intermediate client processing, you might want to set the parameter to 1.0.

Yours,
Laurenz Albe
--
Cybertec | https://www.cybertec-postgresql.com

In response to

Browse pgsql-general by date

  From Date Subject
Next Message Julie Nishimura 2019-10-17 17:20:09 releasing space
Previous Message Reid Thompson 2019-10-17 16:18:42 Re: Can you please tell us how set this prefetch attribute in following lines.

Browse pgsql-hackers by date

  From Date Subject
Next Message Jeremy Finzel 2019-10-17 17:49:38 UPSERT on view does not find constraint by name
Previous Message Reid Thompson 2019-10-17 16:18:42 Re: Can you please tell us how set this prefetch attribute in following lines.

Browse pgsql-performance by date

  From Date Subject
Next Message Michael Lewis 2019-10-17 21:15:21 Reading explain plans- row estimates/actuals on lower nodes vs next level up
Previous Message Reid Thompson 2019-10-17 16:18:42 Re: Can you please tell us how set this prefetch attribute in following lines.