Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1viVhV-008M3J-2C for pgsql-bugs@arkaria.postgresql.org; Wed, 21 Jan 2026 10:44:38 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1viVhU-006Zv7-2j for pgsql-bugs@arkaria.postgresql.org; Wed, 21 Jan 2026 10:44:37 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1viS6U-005LcP-0I for pgsql-bugs@lists.postgresql.org; Wed, 21 Jan 2026 06:54:10 +0000 Received: from mahout.postgresql.org ([2001:4800:3e1:1::227]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1viS6R-001Y9q-0b for pgsql-bugs@lists.postgresql.org; Wed, 21 Jan 2026 06:54:09 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=postgresql.org; s=20171124; h=Message-ID:Date:Reply-To:Cc:From:To:Subject: Content-Transfer-Encoding:MIME-Version:Content-Type:Sender:Content-ID: Content-Description:In-Reply-To:References; bh=zwBJz3R3z6a/625cQi+PUIWi8uCJEEvocBzYiDI70eE=; b=p3ouGuuu9oWSUYccpySj4/gPr9 ym/n8R9cz5lQ/aU9pvOrC7QE2cBum3v1GAPOpUD3vISn/0xrpaOYTG8vboj75xFiH7cqI9Jp+/W31 seyMVhGBhJ270saQHrZoicsonI1AdTbCxVyQni9s6T9krkFYbde6h/vF2eDBBQ0g7mcGZ4IgY/WLZ /twyESoikM4ZTvESinBkWAskZjTJprX9XDwxtzaAZlr6YlOqRPgq+xTp3+G14BAlVERf9Nxnbvyf7 ttwjd7QO3FF6nupRB3/+U6z+RPn+ohpwoiM/qYf5qf34x9/HB0sRgDnNJd1L0hR6ONIvErHAnYfAz xfzzIj9w==; Received: from wrigleys.postgresql.org ([2a02:16a8:dc51::60]) by mahout.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1viS6O-004UDe-09 for pgsql-bugs@lists.postgresql.org; Wed, 21 Jan 2026 06:54:07 +0000 Received: from localhost ([127.0.0.1] helo=wrigleys.postgresql.org) by wrigleys.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1viS6M-007cuQ-0e for pgsql-bugs@lists.postgresql.org; Wed, 21 Jan 2026 06:54:02 +0000 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Subject: BUG #19385: Normal SELECT generates an ineffecifient query plan compare to the prepared SELECT. To: pgsql-bugs@lists.postgresql.org From: PG Bug reporting form Cc: 798604270@qq.com Reply-To: 798604270@qq.com, pgsql-bugs@lists.postgresql.org Date: Wed, 21 Jan 2026 06:53:11 +0000 Message-ID: <19385-b384f1bd063ec84a@postgresql.org> X-Auto-Response-Suppress: All Auto-Submitted: auto-generated List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk The following bug has been logged on the website: Bug reference: 19385 Logged by: Chi Zhang Email address: 798604270@qq.com PostgreSQL version: 18.1 Operating system: ubuntu 24.04 with docker Description: =20 Hi, In the following test case, there are two equivalent simple SELECTs with DISTINCT, however, the normal SELECT is slower than the prepared SELECT. Given that prepared SELECT statements typically generate suboptimal query plans due to the presence of unknown literals, one would expect prepared SELECT to be slower than normal SELECT. However, in this example, the prepared SELECT executes faster, suggesting that there may still be room for optimization in the query plan generation for normal SELECT. ``` CREATE TABLE IF NOT EXISTS t2(c0 int4range ); CREATE TABLE IF NOT EXISTS t3(LIKE t2 INCLUDING CONSTRAINTS); CREATE UNIQUE INDEX i2 ON ONLY t3(c0); INSERT INTO t2 (c0) SELECT int4range(start_val, start_val + (random() * 50 + 1)::int) FROM ( SELECT (random() * 10000)::int AS start_val FROM generate_series(1, 100)) AS random_data; INSERT INTO t3 (c0) SELECT int4range(start_val, start_val + (random() * 50 + 1)::int) FROM ( SELECT (random() * 10000)::int AS start_val FROM generate_series(1, 100)) AS random_data; VACUUM ANALYZE t2, t3; EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT) SELECT DISTINCT t3.c0 FROM t2*, t3 LIMIT (4016369050220296505)::int8; QUERY PLAN ---------------------------------------------------------------------------= ------------------------------------------------- Limit (cost=3D154.25..155.25 rows=3D100 width=3D14) (actual time=3D4.110.= .4.125 rows=3D100.00 loops=3D1) Buffers: shared hit=3D2 -> HashAggregate (cost=3D154.25..155.25 rows=3D100 width=3D14) (actual time=3D4.109..4.118 rows=3D100.00 loops=3D1) Group Key: t3.c0 Batches: 1 Memory Usage: 32kB Buffers: shared hit=3D2 -> Nested Loop (cost=3D0.00..129.25 rows=3D10000 width=3D14) (ac= tual time=3D0.010..1.297 rows=3D10000.00 loops=3D1) Buffers: shared hit=3D2 -> Seq Scan on t2 (cost=3D0.00..2.00 rows=3D100 width=3D0) (actual time=3D0.003..0.008 rows=3D100.00 loops=3D1) Buffers: shared hit=3D1 -> Materialize (cost=3D0.00..2.50 rows=3D100 width=3D14) (= actual time=3D0.000..0.004 rows=3D100.00 loops=3D100) Storage: Memory Maximum Storage: 20kB Buffers: shared hit=3D1 -> Seq Scan on t3 (cost=3D0.00..2.00 rows=3D100 widt= h=3D14) (actual time=3D0.002..0.007 rows=3D100.00 loops=3D1) Buffers: shared hit=3D1 Planning: Buffers: shared hit=3D50 Planning Time: 0.166 ms Execution Time: 4.166 ms (19 rows) PREPARE prepare_query (int8) AS SELECT DISTINCT t3.c0 FROM t2, t3* LIMIT $1; EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT) EXECUTE prepare_query(4016369050220296505); QUERY PLAN ---------------------------------------------------------------------------= ----------------------------------------------------------- Limit (cost=3D0.14..16.32 rows=3D10 width=3D14) (actual time=3D0.018..2.6= 16 rows=3D100.00 loops=3D1) Buffers: shared hit=3D3 -> Unique (cost=3D0.14..161.89 rows=3D100 width=3D14) (actual time=3D0.018..2.608 rows=3D100.00 loops=3D1) Buffers: shared hit=3D3 -> Nested Loop (cost=3D0.14..136.89 rows=3D10000 width=3D14) (ac= tual time=3D0.017..1.237 rows=3D10000.00 loops=3D1) Buffers: shared hit=3D3 -> Index Only Scan using i2 on t3 (cost=3D0.14..9.64 rows= =3D100 width=3D14) (actual time=3D0.009..0.018 rows=3D100.00 loops=3D1) Heap Fetches: 0 Index Searches: 1 Buffers: shared hit=3D2 -> Materialize (cost=3D0.00..2.50 rows=3D100 width=3D0) (a= ctual time=3D0.000..0.004 rows=3D100.00 loops=3D100) Storage: Memory Maximum Storage: 19kB Buffers: shared hit=3D1 -> Seq Scan on t2 (cost=3D0.00..2.00 rows=3D100 widt= h=3D0) (actual time=3D0.005..0.010 rows=3D100.00 loops=3D1) Buffers: shared hit=3D1 Planning Time: 0.041 ms Execution Time: 2.629 ms (17 rows) ```