Planner debug views - Mailing list pgsql-hackers

From Qingqing Zhou
Subject Planner debug views
Date
Msg-id CAJjS0u0U1Z8VKgfMJgbLQvN-_RQS7qg315N2sD+6ZK4pn9KUOQ@mail.gmail.com
Whole thread Raw
Responses Re: Planner debug views
Re: Planner debug views
List pgsql-hackers
Here is a proposal introducing some debugging infrastructure into the
core. The basic idea is to allow us to query the planner search space.
To so do, we can dump related information to csv files and use foreign
table to query them. So here I propose two foreign tables:
 create foreign table pg_planner_rels(rel text, content text) ... create foreign table pg_planner_paths(rel text, path
text,
replacedby text, totalcost float, cheapest text, content text) ...

Where
1. pg_planner_rels consists of RelOptInfo information.
2. pg_planner_paths consists of paths belong to each rel.
3. Field "rel" is a RelOptInfo* pointer so these two tables can join each other.
4. We can further adding subqueries view, or expand pg_planner_paths
table easily adding startup_cost etc.

And an example output is attached. The nice thing about it, is it
reusing the database query power to diagnose database query problems
:-). From the tables, we can find out all paths considered and why
they are discarded.

I have a draft implementation of above idea - main changes including:
1. Keep removed path in a separate list, also the reason of removal
(see "replacedby" field);
2. Change debug_print_rel() family to use StringInfo instead of printf().

I would also suggest we change DEBUG_OPTIMIZER into a GUC, because we
need this ability in release build as well. There is almost no
overhead when GUC is off.

Before I get into more details, I'd like to see if we see this is a
good way to go.

Thoughts?

Regards,
Qingqing


-- query to test
postgres=# explain select a.i, count(a.i) from a join b on a.i=b.i
group by a.i order by a.i limit 1;                                     QUERY PLAN

--------------------------------------------------------------------------------------Limit  (cost=14.47..15.64 rows=1
width=4) ->  GroupAggregate  (cost=14.47..120.67 rows=91 width=4)        Group Key: a.i        ->  Merge Join
(cost=14.47..97.51rows=4450 width=4)              Merge Cond: (a.i = b.i)              ->  Index Only Scan using ai on
a (cost=0.28..45.07
 
rows=600 width=4)              ->  Sort  (cost=14.20..14.72 rows=210 width=4)                    Sort Key: b.i
         ->  Seq Scan on b  (cost=0.00..6.10 rows=210 width=4)
 
(9 rows)

-- after query is done we can see rels
postgres=# select * from pg_planner_rels;  rel   |               content
---------+-------------------------------------2f49b70 | RELOPTINFO (1): rows=600 width=42f49d08 | RELOPTINFO (2):
rows=210width=42f4a590 | RELOPTINFO (1 2): rows=4450 width=41543340 | RELOPTINFO (1): rows=1 width=64
 
(4 rows)

-- and paths
postgres=# select rel, path, replacedby, totalcost, substr(content, 1,
30) from pg_planner_paths ;  rel   |  path   | replacedby | totalcost |             substr
---------+---------+------------+-----------+--------------------------------2f49b70 | 2f4abb8 |            |         1
|IdxScan(1) rows=600 cost=0.28.2f49b70 | 2f4a1f0 |            |        10 | SeqScan(1) rows=600 cost=0.00.2f49b70 |
2f49e10|            |        45 | IdxScan(1) rows=600 cost=0.28.2f49b70 | 2f4d6b8 | 2f4d6b8    |         5 |
BitmapHeapScan(1)rows=600 cos2f49d08 | 2f4e3e0 |            |         6 | SeqScan(2) rows=210 cost=0.00.2f4a590 |
2f4f938|            |        77 | HashJoin(1 2) rows=4450 cost=12f4a590 | 2f4f678 |            |        88 | HashJoin(1
2)rows=4450 cost=82f4a590 | 2f4f330 |            |        98 | MergeJoin(1 2) rows=4450 cost=2f4a590 | 2f4f850 |
   |       140 | NestLoop(1 2) rows=4450 cost=02f4a590 | 2f4f188 |            |      1907 | NestLoop(1 2) rows=4450
cost=02f4a590| 2f4f278 |            |      1942 | NestLoop(1 2) rows=4450 cost=02f4a590 | 2f4f8a8 | 2f4f8a8    |
1908| NestLoop(1 2) rows=4450 cost=02f4a590 | 2f4f700 | 2f4f700    |       105 | MergeJoin(1 2) rows=4450 cost=2f4a590
|2f4eea0 | 2f4f330    |       120 | MergeJoin(1 2) rows=4450 cost=2f4a590 | 2f4f220 | 2f4f278    |      5280 |
NestLoop(12) rows=4450 cost=02f4a590 | 2f4efb8 | 2f4f188    |      5245 | NestLoop(1 2) rows=4450 cost=01543340 |
1543d08|            |         1 | ForeignScan(1) rows=1 cost=0.01543cf8 | 2f49a20 |            |         3 |
ForeignScan(1)rows=17 cost=0.
 
(18 rows)



pgsql-hackers by date:

Previous
From: Josh Berkus
Date:
Subject: Re: pgbench stats per script & other stuff
Next
From: Michael Paquier
Date:
Subject: Re: ALTER TABLE .. ADD PRIMARY KEY .. USING INDEX has dump-restore hazard