[bind10-dev] missing C API for PostgreSQL: row-by-row query result retrieval

Shane Kerr shane at isc.org
Wed Oct 3 12:52:31 UTC 2012


Jinmei,

On Monday, 2012-10-01 20:47:27 -0700, 
JINMEI Tatuya / 神明達哉 <jinmei at isc.org> wrote:
> While doing experiments I mentioned in the other thread(*), I noticed
> that the PostgreSQL's C API misses one important feature except in the
> very latest version, 9.2: the ability of incremental retrieving a
> query result.
> * https://lists.isc.org/pipermail/bind10-dev/2012-October/003866.html
> 
> It seems to be supported in 9.2
> http://www.postgresql.org/docs/9.2/static/libpq-single-row-mode.html,
> but before that it seems we have to store all results of a query in
> memory at once and then process it.  It makes some usage effectively
> unusable (or at least very expensive) such as axfr-out or loading from
> DB in-memory for a very large zone.

Good that this is finally included, it seems to have been something
missing for quite a while:

http://archives.postgresql.org/pgsql-interfaces/2000-09/msg00082.php

> If our next target for the DB backend is PostgreSQL, we need to think
> about how to deal with that, including:
> 
> - Implement everything using pre-9.2 APIs, and say that it won't work
>   well for large scale environments
> - Support both the new and old APIs based on availability, and say
>   that for large scale environments 9.2 or higher will have to be
>   used.

Since 9.2 came out less than a month ago, we can safely assume that
nobody is using it yet. :( (Although perhaps the reported speed
improvements will encourage serious users to jump quickly.)

I definitely think we should use the 9.2 single row mode, although we
clearly can only use this where available.

A third option is:

- Identify the queries we have that can return a large data set, and
  force the results into a loop on the client side.

So, for example, we assuming we want to transfer a zone, we could do
something like:

    SELECT rdtype, ttl, sigtype, rdata, name, rname FROM records 
        WHERE zone_id = ?1
        ORDER by rname, rdtype
	LIMIT 100 

This would give us no more than 100 rows. 

We can then call again, using the last rname and rdtype, like this:

    SELECT rdtype, ttl, sigtype, rdata, name, rname FROM records 
        WHERE (zone_id = ?1) AND (rname >= ?2) AND (rdtype >= ?3)
        ORDER by rname, rdtype
	LIMIT 100 

We continue this until we get less than our maximum 100 rows back.

There is a bit of a corner case when our 100th record is in the middle
of the same rname/rdtype (which is why I have >= and not > there).

It's icky and I'm not sure what the performance penalty would be, but
perhaps better than loading yet another copy of an entire zone into
memory. 

> By the way, MySQL's C API has been supporting incremental retrieval
> for quite some time, so we don't have this particular issue with
> MySQL.

I guess the adage that "programmers like MySQL and DBA's like
PostgreSQL" came about for a reason. :)

--
Shane


More information about the bind10-dev mailing list