Hi all, today I debugged a query that was executing about 100x slower than expected, and was very surprised by what I found. I'm posting to this list to see if this might be an issue that should be fixed in PostgreSQL itself. Below is a simplified version of the query in question: SET work_mem='64MB'; EXPLAIN ANALYZE SELECT * FROM generate_series(1, 1) a, generate_series(1, 1) b UNION SELECT * FROM generate_series(1, 1) a, generate_series(1, 1) b; HashAggregate (cost=80020.01..100020.01 rows=2000000 width=8) (actual time=19.349..23.123 rows=1 loops=1) Group Key: a.a, b.b -> Append (cost=0.01..70020.01 rows=2000000 width=8) (actual time=0.022..0.030 rows=2 loops=1) -> Nested Loop (cost=0.01..20010.01 rows=1000000 width=8) (actual time=0.021..0.022 rows=1 loops=1) -> Function Scan on generate_series a (cost=0.00..10.00 rows=1000 width=4) (actual time=0.014..0.014 rows=1 loops=1) -> Function Scan on generate_series b (cost=0.00..10.00 rows=1000 width=4) (actual time=0.002..0.003 rows=1 loops=1) -> Nested Loop (cost=0.01..20010.01 rows=1000000 width=8) (actual time=0.006..0.007 rows=1 loops=1) -> Function Scan on generate_series a_1 (cost=0.00..10.00 rows=1000 width=4) (actual time=0.002..0.003 rows=1 loops=1) -> Function Scan on generate_series b_1 (cost=0.00..10.00 rows=1000 width=4) (actual time=0.002..0.002 rows=1 loops=1) Planning Time: 0.101 ms Execution Time: 45.986 ms As you can see, it takes over 45ms (!) to execute what appear to be a very simple query. How is this possible? Based on my debugging, I think the following is going on: 1. The query overestimates the final output rows by a factor of 2 million. [1] 2. The executor uses the bad estimate to allocate a huge hash table [2], and the increased work_mem [3] gives it enough rope to hang itself [4]. 3. Somehow EXPLAIN gets confused by this and only ends up tracking 23ms of the query execution instead of 45ms [5]. I'm certainly a novice when it comes to PostgreSQL internals, but I'm wondering if this could be fixed by taking a more dynamic approach for allocating HashAggregate hash tables? Anyway, for my query using UNION ALL was acceptable, so I'm not too troubled by this. I was just really caught by surprise that bad estimates can not only cause bad query plans, but also cause good query plans to execute extremely slowly. I had never seen that before. Best Regards Felix [1] My actual query had bad estimates for other reasons (GIN Index), but that's another story. The query above was of course deliberately designed to have bad estimates. [2] nodeAgg.c: build_hash_table() [3] A lot of queries in my application benefit from increased work_mem. [4] execGrouping.c: nbuckets = Min(nbuckets, (long) ((work_mem * 1024L) / entrysize)); [5] In my actual query it was even worse, only 6 out of 40ms of the total execution time were reported as being spent in the query nodes.