Analysis of set_base_rel_pathlists function and its subfunctions of PostgreSQL
Opts- > random_page_cost;} if (spc_seq_page_cost) / / Sequential read {if (! spc- > opts | | spc- > opts- > seq_page_cost
< 0) *spc_seq_page_cost = seq_page_cost; else *spc_seq_page_cost = spc->Opts- > seq_page_cost;}} / /-get_restriction_qual_cost / * * get_restriction_qual_cost * Compute evaluation costs of a baserel's restriction quals, plus any * movable join quals that have been pushed down to the scan. * Results are returned into * qpqual_cost. * calculate the estimated cost of base rel constraints, including connection conditions pushed down to constraints * * This is a convenience subroutine that works for seqscans and other cases * where all the given quals will be evaluated the hard way. It's not useful * for cost_index (), for example, where the index machinery takes care of * some of the quals. We assume baserestrictcost was previously set by * set_baserel_size_estimates (). * / static void get_restriction_qual_cost (PlannerInfo * root, RelOptInfo * baserel, ParamPathInfo * param_info, QualCost * qpqual_cost) {if (param_info) / / Parametric Information {/ * Include costs of pushed-down clauses * / cost_qual_eval (qpqual_cost, param_info- > ppi_clauses, root) / / evaluate the cost qpqual_cost- > startup + = baserel- > baserestrictcost.startup; qpqual_cost- > per_tuple + = baserel- > baserestrictcost.per_tuple;} else * qpqual_cost = baserel- > baserestrictcost;// without parameterized information, return} / /-cost_qual_eval / * * cost_qual_eval * Estimate the CPU costs of evaluating a WHERE clause directly. * The input can be either an implicitly-ANDed list of boolean * expressions, or a list of RestrictInfo nodes. (The latter is * preferred since it allows caching of the results.) The result includes both an one-time (startup) component, * and a per-evaluation component. * / void cost_qual_eval (QualCost * cost, List * quals, PlannerInfo * root) {cost_qual_eval_context context; ListCell * l; context.root = root; context.total.startup = 0; context.total.per_tuple = 0 / * We don't charge any cost for the implicit ANDing at top level. * / foreach (l, quals) / / traversal linked list {Node * qual = (Node *) lfirst (l); cost_qual_eval_walker (qual, & context); / / traversal expression} * cost = context.total / / return total cost} / /-cost_qual_eval_walker static bool cost_qual_eval_walker (Node * node, cost_qual_eval_context * context) {if (node = = NULL) return false; / * * RestrictInfo nodes contain an eval_cost field reserved for this * routine's use, so that it's not necessary to evaluate the qual clause's * cost more than once. If the clause's cost hasn't been computed yet, * the field's startup value will contain-1. * / if (IsA (node, RestrictInfo)) / / constraint {RestrictInfo * rinfo = (RestrictInfo *) node; if (rinfo- > eval_cost.startup)
< 0)//未计算成本,初始值为-1 { cost_qual_eval_context locContext; locContext.root = context-> < root->Simple_rel_array_size; rti++)
Enter set_plain_rel_pathlist:
(gdb) 452set_plain_rel_pathlist (root, rel, rte); (gdb) stepset_plain_rel_pathlist (root=0x2fd9418, rel=0x2f98278, rte=0x2eaa5d8) at allpaths.c:704704 required_outer = rel- > lateral_relids
Enter create_seqscan_path:
(gdb) stepcreate_seqscan_path (root=0x2fd9418, rel=0x2f98278, required_outer=0x0, parallel_workers=0) at pathnode.c:957957 Path * pathnode = makeNode (Path); (gdb) 969 cost_seqscan (pathnode, root, rel, pathnode- > param_info) (gdb) p * pathnode$2 = {type = T_Path, pathtype = T_SeqScan, parent = 0x2f98278, pathtarget = 0x2f98488, param_info = 0x0, parallel_aware = false, parallel_safe = true, parallel_workers = 0, rows = 0, startup_cost = 0, total_cost = 0, pathkeys = 0x0}
Enter cost_seqscan:
The acquisition of (gdb) 230path- > rows = baserel- > rows;#rows was introduced in the previous section (gdb) p baserel- > rows$4 = 10926. # cost of tablespace sequential scans (gdb) p spc_seq_page_cost$5 = 1#IO cost (gdb) p disk_run_cost$6 = 726
Enter get_restriction_qual_cost:
(gdb) stepget_restriction_qual_cost (root=0x2fd9418, baserel=0x2f98278, param_info=0x0, qpqual_cost=0x7ffe12ca4620) at costsize.c:39993999 if (param_info) # without parameterized information, directly use baserel- > baserestrictcost (gdb) n4008 * qpqual_cost= baserel- > baserestrictcost; (gdb) p baserel- > baserestrictcost$7 = {startup = 0, per_tuple = 0.005000000000001}
Back to cost_seqscan
(gdb) cost_seqscan (path=0x2f98990, root=0x2fd9418, baserel=0x2f98278, param_info=0x0) at costsize.c:248248 startup_cost + = qpqual_cost.startup;...
Execute cost_seqscan, the final path:
(gdb) p * path$8 = {type = T_Path, pathtype = T_SeqScan, parent = 0x2f98278, pathtarget = 0x2f98488, param_info = 0x0, parallel_aware = false, parallel_safe = true, parallel_workers = 0, rows = 10926, startup_cost = 0, total_cost = 2226, pathkeys = 0x0} (gdb) p cpu_run_cost$9 = 1500 (gdb) p disk_run_cost$10 = 726
Go back to the upper function:
(gdb) ncreate_seqscan_path (root=0x2fd9418, rel=0x2f98278, required_outer=0x0, parallel_workers=0) at pathnode.c:971971 return pathnode; (gdb) 972} (gdb) set_plain_rel_pathlist (root=0x2fd9418, rel=0x2f98278, rte=0x2eaa5d8) at allpaths.c:710710 if (rel- > consider_parallel & & required_outer= = NULL)
Continue to execute the build index scan path / TID scan path function:
714 create_index_paths (root, rel); (gdb) 717 create_tidscan_paths (root, rel); (gdb) n718}
The result of the index scan path, rows = 10926, startup_cost = 324.40899999999999999
(gdb) p * rel- > pathlist$14 = {type = T_List, length = 1, head = 0x2fe8d10, tail = 0x2fe8d10} (gdb) p * (Path *) rel- > pathlist- > head- > data.ptr_value$15 = {type = T_BitmapHeapPath, pathtype = T_BitmapHeapScan, parent = 0x2f98278, pathtarget = 0x2f98488, param_info = 0x0, parallel_aware = false, parallel_safe = true, parallel_workers = 0, rows = 10926, startup_cost = 324.40899999999999, total_cost = 1214.299, pathkeys = 0x0}
End the call
(gdb) set_base_rel_pathlists (root=0x2fd9418) at allpaths.c:296296 for (rti = 1; rti
< root->Simple_rel_array_size; rti++) (gdb) 312} (gdb) make_one_rel (root=0x2fd9418, joinlist=0x2f985d8) at allpaths.c:185185 rel = make_rel_from_joinlist (root, joinlist); # DONE!
For the corresponding SQL execution plan, for cost=324.41..1214.30, please refer to the result of index scan path (analyzed in the next section of this source code):
Testdb=# explain analyze verbose select t1.* from t_dwxx T1 where dwbh > '10000' and dwbh
< '20000'; QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------- Bitmap Heap Scan on public.t_dwxx t1 (cost=324.41..1214.30 rows=10926 width=23) (actual time=3.196..4.959 rows=11111 loops=1) Output: dwmc, dwbh, dwdz Recheck Cond: (((t1.dwbh)::text >'10000'::text) AND ((t1.dwbh):: text
< '20000'::text)) Heap Blocks: exact=85 ->Bitmap Index Scan on t_dwxx_pkey (cost=0.00..321.68 rows=10926 width=0) (actual time=3.159..3.159 rows=11111 loops=1) Index Cond: ((t1.dwbh):: text > '10000'::text) AND ((t1.dwbh):: text <' 20000'::text) Planning Time: 0.315 ms Execution Time: 5.673 ms (8 rows) Thank you for your reading The above is the content of "PostgreSQL's set_base_rel_pathlists function and its sub-function analysis". After the study of this article, I believe you have a deeper understanding of the PostgreSQL set_base_rel_pathlists function and its sub-function analysis, and the specific use needs to be verified by practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!