Optimizer Doesn't Push Down Where Expressions on Rollups - Mailing list pgsql-bugs

From Logan Bowers
Subject Optimizer Doesn't Push Down Where Expressions on Rollups
Date
Msg-id 17F738BE-8D45-422C-BAD0-ACA3090BF46D@gmail.com
Whole thread Raw
List pgsql-bugs
Hello, 

I’m running into a performance issue where I’m trying to introduce a rollup into GROUP BY clause. I believe the query planner is missing an optimization when grouping by multiple terms. 

Here’s an example that replicates the problem: 

BEGIN;
CREATE TABLE limitation_demo (c1 integer, c2 integer, c3 integer, c4 integer);

INSERT INTO limitation_demo SELECT
    (random() * 20)::integer,
    (random() * 20)::integer,
    (random() * 20)::integer,
    (random() * 20)::integer
  FROM generate_series(0,10000) AS foo;

CREATE INDEX idx1 ON limitation_demo (c1, c2, c3);

--Good
EXPLAIN SELECT * FROM (SELECT c1,c2,c3, sum(c4) FROM limitation_demo GROUP BY c1,c2,c3) AS foo  WHERE c1 = 1 AND c2 = 5 ;
--Bad
EXPLAIN SELECT * FROM (SELECT c1,c2,c3, sum(c4) FROM limitation_demo GROUP BY c1, c2, ROLLUP(c3)) AS foo  WHERE c1 = 1 AND c2 = 5;
ROLLBACK;


Here are the respective query plans: 

                                    QUERY PLAN
-----------------------------------------------------------------------------------
 GroupAggregate  (cost=0.29..8.32 rows=1 width=20)
   Group Key: limitation_demo.c1, limitation_demo.c2, limitation_demo.c3
   ->  Index Scan using idx1 on limitation_demo  (cost=0.29..8.30 rows=1 width=16)
         Index Cond: ((c1 = 1) AND (c2 = 5))
(4 rows)

                                 QUERY PLAN
----------------------------------------------------------------------------
 HashAggregate  (cost=255.02..360.03 rows=2 width=20)
   Hash Key: limitation_demo.c1, limitation_demo.c2, limitation_demo.c3
   Hash Key: limitation_demo.c1, limitation_demo.c2
   Filter: ((limitation_demo.c1 = 1) AND (limitation_demo.c2 = 5))
   ->  Seq Scan on limitation_demo  (cost=0.00..155.01 rows=10001 width=16)
(5 rows)

Despite being semantically equivalent, I believe, the latter plan with the rollup does not use the index. I believe what is happening is that the WHERE clause is getting pushed down into the inner query without the ROLLUP, but is not with the ROLLUP. 

This is a simplified example. In my real-world use case, the inner query is a view, so I don’t have the option of moving the where clause. 

Can y’all let me know if I should submit this somewhere else? Thanks! 

pgsql-bugs by date:

Previous
From: Tom Lane
Date:
Subject: Re: select big table postgresql crash
Next
From: Andres Freund
Date:
Subject: Re: BUG #16285: bt_metap fails with value is out of range for typeinteger