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 1wmTre-000o7f-2s for pgsql-bugs@arkaria.postgresql.org; Wed, 22 Jul 2026 10:07:47 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wmTrd-00BUZ5-1s for pgsql-bugs@arkaria.postgresql.org; Wed, 22 Jul 2026 10:07:45 +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 1wmQoK-00AnW9-0x for pgsql-bugs@lists.postgresql.org; Wed, 22 Jul 2026 06:52:07 +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.98.2) (envelope-from ) id 1wmQoG-00000001NdX-3kIX for pgsql-bugs@lists.postgresql.org; Wed, 22 Jul 2026 06:52:07 +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=dNprwbC3Oehwu9ScKqBTA5eGAS94QE+ZB9ikdqpXPKo=; b=Ojo0b6a3DlKN8W9KM2h0haFQX5 kUjouJqXfQyZwssuW11AZnDqEMw2DPda0CcAtVJAmO000P43zYnO8fn0pL72BcpQcm4A1nkWJn7Wj zWROmBQD8dPUDxO8t1odz6lVfxtaHZrwfpg19YEZPcOvUsTdqipJ8YwwyBCU17VNY4v65kzK1quQx DAkMU1RU00z/GIGoD6XXcTZMDfAjlb6zb2q4Pidt9Hzlepa3F0qQWV5uatj06RIZuzZXHChR8emPq QviPmVciSZ+DMHm7LiBwIn9/uptsHOp5jlDpP3PfJKs+V7L5ytg5aUEtgVL+TzehL6nhLnWyya+nU oBMidTuw==; 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 1wmQoH-001knf-0A for pgsql-bugs@lists.postgresql.org; Wed, 22 Jul 2026 06:52:05 +0000 Received: from localhost ([127.0.0.1] helo=wrigleys.postgresql.org) by wrigleys.postgresql.org with esmtp (Exim 4.98.2) (envelope-from ) id 1wmQoG-0000000267V-03CP for pgsql-bugs@lists.postgresql.org; Wed, 22 Jul 2026 06:52:04 +0000 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Subject: BUG #19568: Redundant outer DISTINCT adds Sort and Unique above INTERSECT To: pgsql-bugs@lists.postgresql.org From: PG Bug reporting form Cc: 2320415112@qq.com Reply-To: 2320415112@qq.com, pgsql-bugs@lists.postgresql.org Date: Wed, 22 Jul 2026 06:51:33 +0000 Message-ID: <19568-cc05e88af2b80bd1@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: 19568 Logged by: cl hl Email address: 2320415112@qq.com PostgreSQL version: 17.10 Operating system: Linux LAPTOP-2SQAVLB0 6.6.87.2-microsoft Description: =20 ## Description This issue concerns an outer `DISTINCT` applied to an `INTERSECT` result. Since non-`ALL` `INTERSECT` already returns duplicate-free rows, the outer operation cannot change the result. PostgreSQL nevertheless performs a second deduplication. ### Expected Behaviour PostgreSQL should propagate the uniqueness guarantee from `INTERSECT` and remove the outer `DISTINCT`. Both equivalent forms should use the same plan and have comparable execution times. ### Actual Behaviour The outer `DISTINCT` adds `Sort -> Unique` above `HashSetOp Intersect`. With two 500,000-row inputs and 250,000 result rows, five-run median execution time increased from 176.081 ms to 191.225 ms, approximately 8.6%. ## How to repeat ```sql DROP TABLE IF EXISTS intersect_distinct_lhs; DROP TABLE IF EXISTS intersect_distinct_rhs; CREATE TABLE intersect_distinct_lhs (v INTEGER NOT NULL); CREATE TABLE intersect_distinct_rhs (v INTEGER NOT NULL); INSERT INTO intersect_distinct_lhs SELECT g FROM generate_series(1, 500000) AS g; INSERT INTO intersect_distinct_rhs SELECT g FROM generate_series(250001, 750000) AS g; ANALYZE intersect_distinct_lhs; ANALYZE intersect_distinct_rhs; EXPLAIN (ANALYZE, BUFFERS, VERBOSE, SETTINGS, TIMING OFF) SELECT DISTINCT v FROM ( SELECT v FROM intersect_distinct_lhs INTERSECT SELECT v FROM intersect_distinct_rhs ) AS set_result; EXPLAIN (ANALYZE, BUFFERS, VERBOSE, SETTINGS, TIMING OFF) SELECT v FROM ( SELECT v FROM intersect_distinct_lhs INTERSECT SELECT v FROM intersect_distinct_rhs ) AS set_result; ``` Both queries return the same 250,000 rows. The characteristic plans are: ```text with DISTINCT: Unique -> Sort -> HashSetOp Intersect without: HashSetOp Intersect ```