X-Original-To: pgsql-performance-postgresql.org@localhost.postgresql.org Received: from localhost (av.hub.org [200.46.204.144]) by svr1.postgresql.org (Postfix) with ESMTP id 8D0CCD7A1E for ; Wed, 24 Aug 2005 17:43:53 -0300 (ADT) Received: from svr1.postgresql.org ([200.46.204.71]) by localhost (av.hub.org [200.46.204.144]) (amavisd-new, port 10024) with ESMTP id 82006-08 for ; Wed, 24 Aug 2005 20:43:50 +0000 (GMT) Received: from zproxy.gmail.com (zproxy.gmail.com [64.233.162.196]) by svr1.postgresql.org (Postfix) with ESMTP id 45064D7A12 for ; Wed, 24 Aug 2005 17:43:49 -0300 (ADT) Received: by zproxy.gmail.com with SMTP id 8so113823nzo for ; Wed, 24 Aug 2005 13:43:51 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:to:subject:mime-version:content-type:content-transfer-encoding:content-disposition; b=O11vR1UMsMxWbs+ugX+la4+iLi+numSsTJc+ZIQzTnMVSBGm4MEcQBuUmrFBBuXdXVhuhMyJv5Dy+5UWwWpLIIqiiMsp1Wo4qsl2+MOmTWk8WWMdc7S66kGLqc/5o22zPTi18hOg6bh62XS8MG9nqasi1lrdpHFlm/d6N/Uq9rs= Received: by 10.37.2.4 with SMTP id e4mr3022nzi; Wed, 24 Aug 2005 13:43:51 -0700 (PDT) Received: by 10.36.158.7 with HTTP; Wed, 24 Aug 2005 13:43:51 -0700 (PDT) Message-ID: Date: Wed, 24 Aug 2005 14:43:51 -0600 From: Mark Fox To: pgsql-performance@postgresql.org Subject: Performance indexing of a simple query Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline X-Virus-Scanned: by amavisd-new at hub.org X-Spam-Status: No, hits=0.177 required=5 tests=[AWL=0.153, RCVD_BY_IP=0.024] X-Spam-Level: X-Archive-Number: 200508/401 X-Sequence-Number: 14148 I have a table called 'jobs' with several million rows, and the only columns that are important to this discussion are 'start_time' and 'completion_time'. The sort of queries I want to execute (among others) are like: SELECT * FROM jobs WHERE completion_time > SOMEDATE AND start_time < SOMEDATE; In plain english: All the jobs that were running at SOMEDATE. The result of the query is on the order of 500 rows. I've got seperate indexes on 'start_time' and 'completion_time'. Now, if SOMEDATE is such that the number of rows with completion_time > SOMEDATE is small (say 10s of thousands), the query uses index scans and executes quickly. If not, the query uses sequential scans and is unacceptably slow (a couple of minutes). I've used EXPLAIN and EXPLAIN ANALYZE to confirm this. This makes perfect sense to me. I've played with some of the memory settings for PostgreSQL, but none has had a significant impact. Any ideas on how to structure the query or add/change indexes in such a way to improve its performance? In desperation, I tried using a subquery, but unsurprisingly it made no (positive) difference. I feel like there might be a way of using an index on both 'completion_time' and 'start_time', but can't put a temporal lobe on the details. Mark