#!/usr/bin/perl use strict; use Getopt::Std; my %opt; getopts('h', \%opt); if ( $opt{h} ) { print "Usage:\n$0 < LOGFILE\n"; exit(0); } my $state=0; my %vals; my @tst=qw( rnd clt ); my $curtst; while(<>) { chomp; if ( $state == 0 ) { if ( /^==\s*(.*?)\s*\[(\w+)\]==/ ) { $state=1; $curtst=$2; $vals{$curtst}{name} = $1; } } elsif ( $state == 1 ) { if ( /^Time: ([\d,]+)/ ) { my $n = $1; $n=~s/,/./; $vals{$curtst}{totaltime} += $n; $vals{$curtst}{nquery}++; } elsif ( /^\s+a\s*$/ ) { $state=2; } } elsif ($state==2) { #parse index root page if ( !/row/ ) { if ( !/^--------/ ) { $vals{$curtst}{volume} += boxsize( grep {length $_} split(/[\s,\(\)]+/, $_) ); $vals{$curtst}{tuples}++; } } else { $state = 3; $vals{$curtst}{avg_volume} = $vals{$curtst}{volume} / (8.0*$vals{$curtst}{tuples}); } } elsif ($state==3) { #get heap size if ( /^\s*(\d+)\s*$/ ) { $vals{$curtst}{heap_blks} = $1; $state=4; } } elsif ($state==4) { #get index size if ( /^\s*(\d+)\s*$/ ) { $vals{$curtst}{idx_blks} = $1; $state=5; } } elsif ($state==5) { #wait pg_statio_user_tables if ( /^-----/ ) { $state = 6; } } elsif ($state==6) { #parse pg_statio_user_tables if ( /\|/ ) { my $str = $_; local $_; my @tvals = grep { length $_ } split(/[\s\|]+/, $str); my %add=( relid=>$tvals[0], relname=>$tvals[2], heap_blks_read=>$tvals[3], heap_blks_hit=>$tvals[4], idx_blks_read=>$tvals[5], idx_blks_hit=>$tvals[6], ); if ( $add{relname}=~/_$curtst$/ ) { $vals{$curtst} = { %{$vals{$curtst}}, %add }; } } else { $state=7; } } elsif ($state==7) { #wait pg_statio_user_indexes if ( /^-----/ ) { $state = 8; } } elsif ($state==8) { #parse pg_statio_user_indexes if ( /\|/ ) { my $str = $_; local $_; my @tvals = grep { length $_ } split(/[\s\|]+/, $str); my %add=( relname=>$tvals[3], indexrelid=>$tvals[1], indexrelname=>$tvals[4], ); if ( $add{relname}=~/_$curtst$/ ) { $vals{$curtst} = { %{$vals{$curtst}}, %add }; } } else { $state=0; } } } foreach my $k ( keys %vals ) { showstat(%{$vals{$k}}); } sub showstat { my %vals=@_; print "====$vals{name}====\n\tTime: $vals{totaltime} msec ($vals{nquery} queries)\n"; print "\tAvg volume: $vals{avg_volume}\n"; local $_; print"\t".join("\n\t", map { /^(idx|heap)_blks/; my $p=( /blks$/ || $vals{$_} == 0 || 1) ? '' : sprintf("\t(%.2f%%)",100.0 * $vals{$_} / $vals{"${1}_blks"} ); "$_\t=> $vals{$_} $p" } sort grep { /^(idx|heap)_blks/ } keys %vals),"\n"; } sub boxsize { my @b = @_; return ( ($b[3]-$b[0])*($b[4]-$b[1])*($b[5]-$b[2]) ); }