Received: from maia.hub.org (maia-2.hub.org [200.46.204.251]) by mail.postgresql.org (Postfix) with ESMTP id 584F7633100 for ; Wed, 12 May 2010 02:41:54 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.251]) (amavisd-maia, port 10024) with ESMTP id 70103-08 for ; Wed, 12 May 2010 05:41:47 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from sargon.lncsa.com (mail.lncsa.com [213.215.28.11]) by mail.postgresql.org (Postfix) with ESMTP id 68713632C3B for ; Wed, 12 May 2010 02:41:47 -0300 (ADT) Received: from localhost (localhost.localdomain [127.0.0.1]) by sargon.lncsa.com (Postfix) with ESMTP id 85456302541E for ; Wed, 12 May 2010 07:41:45 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at lncsa.com Received: from sargon.lncsa.com ([127.0.0.1]) by localhost (sargon.lncsa.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id u14yB0HGQdju for ; Wed, 12 May 2010 07:41:45 +0200 (CEST) Received: from zenon.apartia.fr (zenon.apartia.fr [10.0.3.1]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "zenon.apartia.fr", Issuer "ca.apartia.fr" (verified OK)) by sargon.lncsa.com (Postfix) with ESMTP id 64FF4301E6F3 for ; Wed, 12 May 2010 07:41:45 +0200 (CEST) Received: from delos.apartia.fr (delos.apartia.fr [10.0.3.107]) by zenon.apartia.fr (Postfix) with ESMTP id 0D9165983E907 for ; Wed, 12 May 2010 07:41:44 +0200 (CEST) Received: by delos.apartia.fr (Postfix, from userid 1000) id E43482028391A; Wed, 12 May 2010 07:41:44 +0200 (CEST) Date: Wed, 12 May 2010 07:41:44 +0200 From: Louis-David Mitterrand To: pgsql-sql@postgresql.org Subject: best paging strategies for large datasets? Message-ID: <20100512054144.GA8762@apartia.fr> Mail-Followup-To: pgsql-sql@postgresql.org MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-0.001 tagged_above=-5 required=5 tests=BAYES_40=-0.001 X-Spam-Level: X-Archive-Number: 201005/44 X-Sequence-Number: 34092 Hi, I have a large dataset (page 1 at http://www.cruisefish.net/stat.md) and am in the process of developping a pager to let users leaf through it (30K rows). Ideally I'd like to know when requesting any 'page' of data where I am within the dataset: how many pages are available each way, etc. Of course that can be done by doing a count(*) query before requesting a limit/offset subset. But the main query is already quite slow, so I'd like to minimize them. But I am intrigued by window functions, especially the row_number() and ntile(int) ones. Adding "row_number() over (order by )" to my query will return the total number of rows in the first row, letting my deduce the number of pages remaining, etc. row_number() apparently adds very little cost to the main query. And ntile(buckets) seems nice too but I need the total row count for it to contain a 'page' number: ntile(row_count/page_size). What better "paging" strategies are out there? Thanks,