The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Pg::Explain::Node - Class representing single node from query plan

VERSION

Version 2.7

SYNOPSIS

Quick summary of what the module does.

Perhaps a little code snippet.

    use Pg::Explain::Node;

    my $foo = Pg::Explain::Node->new();
    ...

FUNCTIONS

id

Unique identifier of this node in this explain. It's read-only, autoincrementing integer.

actual_loops

Returns number how many times current node has been executed.

This information is available only when parsing EXPLAIN ANALYZE output - not in EXPLAIN output.

actual_rows

Returns amount of rows current node returnes in single execution (i.e. if given node was executed 10 times, you have to multiply actual_rows by 10, to get full number of returned rows.

This information is available only when parsing EXPLAIN ANALYZE output - not in EXPLAIN output.

actual_time_first

Returns time (in miliseconds) how long it took PostgreSQL to return 1st row from given node.

This information is available only when parsing EXPLAIN ANALYZE output - not in EXPLAIN output.

actual_time_last

Returns time (in miliseconds) how long it took PostgreSQL to return all rows from given node. This number represents single execution of the node, so if given node was executed 10 times, you have to multiply actual_time_last by 10 to get total time of running of this node.

This information is available only when parsing EXPLAIN ANALYZE output - not in EXPLAIN output.

estimated_rows

Returns estimated number of rows to be returned from this node.

estimated_row_width

Returns estimated width (in bytes) of single row returned from this node.

estimated_startup_cost

Returns estimated cost of starting execution of given node. Some node types do not have startup cost (i.e., it is 0), but some do. For example - Seq Scan has startup cost = 0, but Sort node has startup cost depending on number of rows.

This cost is measured in units of "single-page seq scan".

estimated_total_cost

Returns estimated full cost of given node.

This cost is measured in units of "single-page seq scan".

workers_launched

How many worker processes this node launched.

workers

How many workers was this node processed on. Always set to at least 1.

type

Textual representation of type of current node. Some types for example:

  • Index Scan

  • Index Scan Backward

  • Limit

  • Nested Loop

  • Nested Loop Left Join

  • Result

  • Seq Scan

  • Sort

buffers

Information about inclusive buffers usage in given node. It's either undef, or object of Pg::Explain::Buffers class.

scan_on

Hashref with extra information in case of table scans.

For Seq Scan it contains always 'table_name' key, and optionally 'table_alias' key.

For Index Scan and Backward Index Scan, it also contains (always) 'index_name' key.

extra_info

ArrayRef of strings, each contains textual information (leading and tailing spaces removed) for given node.

This is not always filled, as it depends heavily on node type and PostgreSQL version.

sub_nodes

ArrayRef of Pg::Explain::Node objects, which represent sub nodes.

For more details, check ->add_sub_node method description.

initplans

ArrayRef of Pg::Explain::Node objects, which represent init plan.

For more details, check ->add_initplan method description.

initplans_metainfo

ArrayRef of Hashrefs, where each hashref can contains:

  • 'name' - name of the InitPlan, generally number

  • 'returns' - string listing what the initplan returns. Generally a list of $X values (where X is 0 or positive integer) separated by comma.

For more details, check ->add_initplan method description.

subplans

ArrayRef of Pg::Explain::Node objects, which represent sub plan.

For more details, check ->add_subplan method description.

ctes

HashRef of Pg::Explain::Node objects, which represent CTE plans.

For more details, check ->add_cte method description.

cte_order

ArrayRef of names of CTE nodes in given node.

For more details, check ->add_cte method description.

never_executed

Returns true if given node was not executed, according to plan.

parent

Parent node of current node, or undef if it's top node.

exclusive_fix

Numeric value that will be added to total_exclusive_time. It is set by Pg::Explain::check_for_exclusive_time_fixes method once after parsing the explain.

new

Object constructor.

explain

Returns/sets Pg::Explain for this node.

Also, calls $explain->node( $id, $self );

add_extra_info

Adds new line of extra information to explain node.

It will be available at $node->extra_info (returns arrayref)

Extra_info is used by some nodes to provide additional information. For example - for Sort nodes, they usually contain informtion about used memory, used sort method and keys.

add_trigger_time

Adds new information about trigger time.

It will be available at $node->trigger_times (returns arrayref)

add_subplan

Adds new subplan node.

It will be available at $node->subplans (returns arrayref)

Example of plan with subplan:

 # explain select *, (select oid::int4 from pg_class c2 where c2.relname = c.relname) - oid::int4 from pg_class c;
                                               QUERY PLAN
 ------------------------------------------------------------------------------------------------------
  Seq Scan on pg_class c  (cost=0.00..1885.60 rows=227 width=200)
    SubPlan
      ->  Index Scan using pg_class_relname_nsp_index on pg_class c2  (cost=0.00..8.27 rows=1 width=4)
            Index Cond: (relname = $0)
 (4 rows)

add_initplan

Adds new initplan node.

Expects to get node object and hashred with metainformation.

It will be available at $node->initplans (returns arrayref) and $node->initplans_metainfo (also arrayref);

Example of plan with initplan:

 # explain analyze select 1 = (select 1);
                                          QUERY PLAN
 --------------------------------------------------------------------------------------------
  Result  (cost=0.01..0.02 rows=1 width=0) (actual time=0.033..0.035 rows=1 loops=1)
    InitPlan
      ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual time=0.003..0.005 rows=1 loops=1)
  Total runtime: 0.234 ms
 (4 rows)

add_cte

Adds new cte node. CTE has to be named, so this function requires 2 arguments: name, and cte object itself.

It will be available at $node->cte( name ), or $node->ctes (returns hashref).

Since we need order (ctes are stored unordered, in hash), there is also $node->cte_order() which returns arrayref of names.

cte

Returns CTE object that has given name.

add_sub_node

Adds new sub node.

It will be available at $node->sub_nodes (returns arrayref)

Sub nodes are nodes that are used by given node as data sources.

For example - "Join" node, has 2 sources (sub_nodes), which are table scans (Seq Scan, Index Scan or Backward Index Scan) over some tables.

Example plan which contains subnode:

 # explain select * from test limit 1;
                           QUERY PLAN
 --------------------------------------------------------------
  Limit  (cost=0.00..0.01 rows=1 width=4)
    ->  Seq Scan on test  (cost=0.00..14.00 rows=1000 width=4)
 (2 rows)

Node 'Limit' has 1 sub_plan, which is "Seq Scan"

get_struct

Function which returns simple, not blessed, hashref with all information about given explain node and it's children.

This can be used for debug purposes, or as a base to print information to user.

Output looks like this:

 {
     'estimated_rows'         => '10000',
     'estimated_row_width'    => '148',
     'estimated_startup_cost' => '0',
     'estimated_total_cost'   => '333',
     'scan_on'                => { 'table_name' => 'tenk1', },
     'type'                   => 'Seq Scan',
 }

total_inclusive_time

Method for getting total node time, summarized with times of all subnodes, subplans and initplans - which is basically ->actual_loops * ->actual_time_last.

total_rows

Method for getting total number of rows returned by current node. This takes into account parallelization and multiple loops.

total_rows_removed

Sum of rows removed by:

  • Conflict Filter

  • Filter

  • Index Recheck

  • Join Filter

in given node.

total_exclusive_time

Method for getting total node time, without times of subnodes - which amounts to time PostgreSQL spent running this paricular node.

total_exclusive_buffers

Method for getting total buffers used by node, without buffers used by subnodes.

all_subnodes

Returns list of all subnodes of current node.

all_recursive_subnodes

Returns list of all subnodes of current node and its subnodes, and their subnodes, and ...

all_parents

Returns list of all nodes that are "above" given node in explain.

List can be empty if it's top level node.

is_analyzed

Returns 1 if the explain node it represents was generated by EXPLAIN ANALYZE. 0 otherwise.

as_text

Returns textual representation of explain nodes from given node down.

This is used to build textual explains out of in-memory data structures.

anonymize_gathering

First stage of anonymization - gathering of all possible strings that could and should be anonymized.

_make_lexer

Helper function which creates HOP::Lexer based lexer for given line of input

anonymize_substitute

Second stage of anonymization - actual changing strings into anonymized versions.

AUTHOR

hubert depesz lubaczewski, <depesz at depesz.com>

BUGS

Please report any bugs or feature requests to depesz at depesz.com.

SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc Pg::Explain::Node

COPYRIGHT & LICENSE

Copyright 2008-2023 hubert depesz lubaczewski, all rights reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.