Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.80) (envelope-from ) id 1X9QCU-0007F3-3U for pgsql-performance@arkaria.postgresql.org; Tue, 22 Jul 2014 02:53:10 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.80) (envelope-from ) id 1X9QCT-0007hI-04 for pgsql-performance@arkaria.postgresql.org; Tue, 22 Jul 2014 02:53:09 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1X9QCR-0007fG-Kp for pgsql-performance@postgresql.org; Tue, 22 Jul 2014 02:53:07 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by magus.postgresql.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1X9QCO-0002V3-19 for pgsql-performance@postgresql.org; Tue, 22 Jul 2014 02:53:06 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.14.4/8.14.4) with ESMTP id s6M2r1SC004382; Mon, 21 Jul 2014 22:53:01 -0400 From: Tom Lane To: johno cc: pgsql-performance@postgresql.org Subject: Re: Slow query with indexed ORDER BY and LIMIT when using OR'd conditions In-reply-to: References: Comments: In-reply-to johno message dated "Mon, 21 Jul 2014 23:09:19 +0200" Date: Mon, 21 Jul 2014 22:53:01 -0400 Message-ID: <4381.1405997581@sss.pgh.pa.us> X-Pg-Spam-Score: -1.9 (-) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-performance Precedence: bulk Sender: pgsql-performance-owner@postgresql.org johno writes: > I am trying to optimize a simple query that returns first 100 rows that > have been updated since a given timestamp (ordered by timestamp and id > desc). If there are several rows with the same timestamp I need to a > second condition, that states that I want to return rows having the given > timestamp and id > given id. > The obvious query is > SELECT * FROM register_uz_accounting_entities > WHERE effective_on > '2014-07-11' OR (effective_on = '2014-07-11' AND > id > 1459) > ORDER BY effective_on, id > LIMIT 100 A more readily optimizable query is SELECT * FROM register_uz_accounting_entities WHERE (effective_on, id) > ('2014-07-11'::date, 1459) ORDER BY effective_on, id LIMIT 100 This formulation allows the planner to match both the WHERE and ORDER BY clauses directly to the two-column index. > I've tried to optimize this query by pushing down the limit and order by's > into explicit subselects. As noted earlier, that's unlikely to be an improvement, because on its face it specifies more computation. Postgres is not terribly bright about UNIONs, either. regards, tom lane -- Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-performance