Search Postgresql Archives

Re: Understanding EXPLAIN ANALYZE output

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thursday February 10 2005 5:01, David Fetter wrote:
> On Thu, Feb 10, 2005 at 05:19:41PM -0500, Tom Lane wrote:
> > David Fetter <david@xxxxxxxxxx> writes:
> > > I'd be delighted to, but I'm not sure how to see to it
> > > that EXPLAIN gets the CMD_SELECT flag.  What all files
> > > need to change to effect this?  Or have I drastically
> > > misunderstood what's involved?
> >
> > It doesn't.  See
> > http://archives.postgresql.org/pgsql-committers/2005-02/msg0
> >0073.php
>
> Yay!!
>
> Thanks a big bunch, Tom :)

Doodz, u r so phat!  We'd still be working out who
should be invited to the first requirements analysis 
meeting if this were at company X...

This is close but my regexes are not quite right...

CREATE TYPE pg_explain_analyze_in AS (
    exp  text
);

CREATE TYPE pg_explain_analyze_out AS (
        node_id integer,
        node varchar,
        parent_node_id integer,
        level integer,
        index varchar,
        relation varchar,
        plan_startup_cost float,
        plan_total_cost float,
        plan_rows bigint,
        plan_width integer,
        act_startup_cost float,
        act_total_cost float,
        act_rows bigint,
        act_loops bigint,
        condition varchar,
        filter varchar,
        total_time float,
        raw_out varchar
);

CREATE OR REPLACE FUNCTION pg_explain_analyze(query text) RETURNS SETOF pg_explain_analyze_out AS $$
DECLARE
    row  pg_explain_analyze_in;
    ret  pg_explain_analyze_out;
    i    integer;
    indent integer;
BEGIN
    i = 0;
    FOR row IN EXECUTE 'EXPLAIN ANALYZE ' || query LOOP
      ret.node_id           := i;
      row.exp               := replace(row.exp, '->  ', '');
      ret.node              := substring(row.exp FROM '[->  ]?(\\S[^\\(:]+) \\(');
      ret.parent_node_id    := -1;
      ret.level             := length(substring(row.exp FROM '^(\\s*)\\S'));
      ret.index             := substring(row.exp FROM 'Index Scan using (\\S+) on \\S+');
      ret.relation          := substring(row.exp FROM 'Scan using \\S+ on (\\S+)');
      ret.plan_startup_cost := substring(row.exp FROM 'cost=(\\d+\\.\\d+)');
      ret.plan_total_cost   := substring(row.exp FROM 'cost=\\d+\\.\\d+\\.\\.(\\d+\\.\\d+) rows');
      ret.plan_rows         := substring(row.exp FROM ' rows=([[:digit:]]+) width');
      ret.plan_width        := substring(row.exp FROM ' width=([[:digit:]]+)');
      ret.act_startup_cost  := substring(row.exp FROM ' width=([[:digit:]]+)');
      ret.act_total_cost    := substring(row.exp FROM ' width=([[:digit:]]+)');
      ret.act_startup_cost  := substring(row.exp FROM 'time=(\\d+\\.\\d+)');
      ret.act_total_cost    := substring(row.exp FROM 'time=\\d+\\.\\d+\\.\\.(\\d+\\.\\d+) rows');
      ret.act_rows          := substring(row.exp FROM ' rows=([[:digit:]]+) loops');
      ret.act_loops         := substring(row.exp FROM ' rows=[[:digit:]]+ loops=([[:digit:]]+)\\)');
      ret.condition         := substring(row.exp FROM 'Cond: \\((\\.+)\\)');
      ret.filter            := substring(row.exp FROM 'Filter: \\((\\.*)\\)');
      ret.total_time        := substring(row.exp FROM 'Total runtime: (\\d+\\.\\d+) ms');
      ret.raw_out           := row.exp;

      IF substring(row.exp FROM '\\S') IS NOT NULL THEN
          RETURN NEXT ret; 
      END IF;
      i := i + 1;
    END LOOP;
    
    RETURN;
END;
$$ LANGUAGE plpgsql VOLATILE STRICT;


% psql -c "explain analyze select * from foobarbaz_view where id < 3;"
                                                        QUERY PLAN                                                        
--------------------------------------------------------------------------------------------------------------------------
 Nested Loop  (cost=0.00..15.13 rows=2 width=12) (actual time=0.060..0.090 rows=2 loops=1)
   ->  Nested Loop  (cost=0.00..9.08 rows=2 width=12) (actual time=0.043..0.059 rows=2 loops=1)
         ->  Index Scan using baz_pkey on baz  (cost=0.00..3.03 rows=2 width=8) (actual time=0.017..0.021 rows=2 loops=1)
               Index Cond: (id < 3)
         ->  Index Scan using bar_pkey on bar  (cost=0.00..3.01 rows=1 width=8) (actual time=0.012..0.014 rows=1 loops=2)
               Index Cond: ("outer".bar_id = bar.id)
   ->  Index Scan using foo_pkey on foo  (cost=0.00..3.01 rows=1 width=4) (actual time=0.010..0.011 rows=1 loops=2)
         Index Cond: ("outer".foo_id = foo.id)
 Total runtime: 0.226 ms
(9 rows)

% psql -c "SELECT case when node notnull then node||'(cost='||plan_startup_cost||'..'||plan_total_cost||' rows='||plan_rows||' width='||plan_width||') (actual time='||act_startup_cost||'..'||act_total_cost||' rows='||act_rows||' loops='||act_loops||' per row='||case when act_rows > 0 then to_char(act_total_cost/act_rows, '9.999') else '0.00' end||')' else 'Total runtime: '||total_time||' ms' end FROM pg_explain_analyze('select * from foobarbaz_view where id < 3');"
                                                          case                                                           
-------------------------------------------------------------------------------------------------------------------------
 Nested Loop (cost=0..15.13 rows=2 width=12) (actual time=0.058..0.088 rows=2 loops=1 per row=  .044)
 Nested Loop (cost=0..9.08 rows=2 width=12) (actual time=0.04..0.056 rows=2 loops=1 per row=  .028)
 Index Scan using baz_pkey on baz (cost=0..3.03 rows=2 width=8) (actual time=0.016..0.02 rows=2 loops=1 per row=  .010)
 
 Index Scan using bar_pkey on bar (cost=0..3.01 rows=1 width=8) (actual time=0.011..0.012 rows=1 loops=2 per row=  .012)
 
 Index Scan using foo_pkey on foo (cost=0..3.01 rows=1 width=4) (actual time=0.01..0.011 rows=1 loops=2 per row=  .011)
 
 Total runtime: 0.2 ms
(9 rows)



---------------------------(end of broadcast)---------------------------
TIP 6: Have you searched our list archives?

               http://archives.postgresql.org

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Postgresql Jobs]     [Postgresql Admin]     [Postgresql Performance]     [Linux Clusters]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Postgresql & PHP]     [Yosemite]
  Powered by Linux