Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nmQ43-0000t9-HW for pgsql-performance@arkaria.postgresql.org; Thu, 05 May 2022 01:13:55 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1nmQ32-0001PP-NI for pgsql-performance@arkaria.postgresql.org; Thu, 05 May 2022 01:12:52 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nmQ32-0001PG-8e for pgsql-performance@lists.postgresql.org; Thu, 05 May 2022 01:12:52 +0000 Received: from mail.webkr.de ([78.47.173.34]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nmQ2v-0006Oo-Ec for pgsql-performance@lists.postgresql.org; Thu, 05 May 2022 01:12:51 +0000 Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id E31A61A194D for ; Thu, 5 May 2022 03:12:42 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=webkr.de; s=dkim; t=1651713163; h=from:subject:date:message-id:to:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=zr60xprlwdD3yfkfMpqgHxLx1aDZVuQXnd3IoZpp9C4=; b=TWRW4YPH1GDJMaveq4lCfckAgLAccpj+gORguvqWdMgbeYcpMQCqoIzIUGrzPy2ZHT1hED jnXR/SmhUznUK5VfxKNCvBQbuiboIWou7SqeTyjuYyV0pMbflS5KlDJ9wp0T/o/cizbbw0 mJrakOlyI6GQFFJ+e+wRPppG0StKaeU= From: =?UTF-8?Q?Andr=C3=A9_H=C3=A4nsel?= To: "'Pgsql Performance'" References: <014601d8600c$e15aadc0$a4100940$@webkr.de> In-Reply-To: Subject: RE: Why is there a Sort after an Index Only Scan? Date: Thu, 5 May 2022 03:12:40 +0200 Message-ID: <015101d8601d$37df5190$a79df4b0$@webkr.de> MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Thread-Index: AQJUs55e01R53ndrs3J+EiO2l5rJFwGrbK3LrAlrVpA= Content-Language: de X-Last-TLS-Session-Version: TLSv1 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk > They are sorted by order_id only within sets of the same = shipping_date, which is not good enough. =20 Ah yes, that totally makes sense for the general case. > so maybe you can just tweak that application to test if the start and = end dates are the same and use equality when they are. I definitely can. But now I have a followup question, which probably should have been a = separate question all along. I have modified the example a bit to have a = more natural date distribution and I got rid of the weird shipping_date = condition and actually made it different dates, so the index order is = out of the picture. I also added some statistics so Postgres knows about = the relationship between the columns. https://dbfiddle.uk/?rdbms=3Dpostgres_14&fiddle=3D54c7774432e896e3c0e89d8= 084c4b194 After inserting more rows, Postgres still chooses a scan on the primary = key instead of using the index. Limit (cost=3D0.43..296.63 rows=3D50 width=3D4) (actual = time=3D1052.692..1052.737 rows=3D50 loops=3D1) -> Index Scan using orders_test_pkey on orders_test = (cost=3D0.43..71149.43 rows=3D12010 width=3D4) (actual = time=3D1052.690..1052.728 rows=3D50 loops=3D1) Filter: ((shipping_date >=3D '2022-04-30'::date) AND = (shipping_date <=3D '2022-05-01'::date)) Rows Removed by Filter: 1998734 By setting the CPU costs to 0 (last block in the fiddle) I can force the = use of the previous plan and as I already suspected it is much better: Limit (cost=3D101.00..101.00 rows=3D50 width=3D4) (actual = time=3D4.835..4.843 rows=3D50 loops=3D1) -> Sort (cost=3D101.00..101.00 rows=3D12010 width=3D4) (actual = time=3D4.833..4.837 rows=3D50 loops=3D1) Sort Key: order_id Sort Method: top-N heapsort Memory: 27kB -> Index Scan using orders_test_shipping_date_idx on = orders_test (cost=3D0.00..101.00 rows=3D12010 width=3D4) (actual = time=3D0.026..3.339 rows=3D11266 loops=3D1) Index Cond: ((shipping_date >=3D '2022-04-30'::date) AND = (shipping_date <=3D '2022-05-01'::date)) Is it overestimating the cost of the sorting?