The following bug has been logged on the website:
Bug reference: 19569
Logged by: cl hl
Email address: 2320415112@qq.com
PostgreSQL version: 17.10
Operating system: Linux LAPTOP-2SQAVLB0 6.6.87.2-microsoft-standard-
Description:
## Description
This issue concerns an outer `DISTINCT` applied to an `EXCEPT` result.
Non-`ALL` `EXCEPT` already removes duplicates, so applying `DISTINCT` again
is semantically redundant. PostgreSQL retains the additional operation.
### Expected Behaviour
PostgreSQL should use the duplicate-free property of `EXCEPT` and eliminate
the outer `DISTINCT`. The original and simplified forms should receive
equivalent plans.
### Actual Behaviour
The outer `DISTINCT` adds `Sort -> Unique` above `HashSetOp Except`. With
two 500,000-row inputs and 250,000 result rows, five-run medians were
184.393 ms with the redundant operation and 181.401 ms without it,
approximately 1.6% slower. This timing difference is small enough to overlap
runtime variation, but the extra plan operators are deterministic.
## How to repeat
```sql
DROP TABLE IF EXISTS except_distinct_lhs;
DROP TABLE IF EXISTS except_distinct_rhs;
CREATE TABLE except_distinct_lhs (v INTEGER NOT NULL);
CREATE TABLE except_distinct_rhs (v INTEGER NOT NULL);
INSERT INTO except_distinct_lhs
SELECT g FROM generate_series(1, 500000) AS g;
INSERT INTO except_distinct_rhs
SELECT g FROM generate_series(250001, 750000) AS g;
ANALYZE except_distinct_lhs;
ANALYZE except_distinct_rhs;
EXPLAIN (ANALYZE, BUFFERS, VERBOSE, SETTINGS, TIMING OFF)
SELECT DISTINCT v
FROM (
SELECT v FROM except_distinct_lhs
EXCEPT
SELECT v FROM except_distinct_rhs
) AS set_result;
EXPLAIN (ANALYZE, BUFFERS, VERBOSE, SETTINGS, TIMING OFF)
SELECT v
FROM (
SELECT v FROM except_distinct_lhs
EXCEPT
SELECT v FROM except_distinct_rhs
) AS set_result;
```
Both queries return the same 250,000 rows. The characteristic plans are:
```text
with DISTINCT: Unique -> Sort -> HashSetOp Except
without: HashSetOp Except
```