You should just have to reroute the log file from the /dev/null to a real file. The default logfile options should work.
The Output:
#!/usr/bin/perl use strict; use warnings; use Getopt::Long; my $sort_fld = 'tot'; my $show = 25; GetOptions ("show=i" => \$show, "sort=s" => \$sort_fld) || usage('Inva +lid Option'); my $fn = $ARGV[0] || usage('Please specify a logfile'); usage("$fn does not exist") if (! -e $fn); usage("$fn is not readable. Check permissions") if (! -r $fn); usage("$fn is 0 size") if (-z $fn); usage("$fn is not a regular file") if (! -f $fn); usage('Invalid sort option') if (! ($sort_fld eq 'tot' or $sort_fld eq + 'avg' or $sort_fld eq 'cost')); my ($lines ) = `wc -l $fn`; $lines =~ s/\D+//g; my %q; my $get_q = 0; my $query = ''; my $buffer = ''; open(FH,'<',$fn) or die "Could not open $fn: $!"; print "Reading file...\n"; my $cnt = 0; while (my $line = <FH>) { if ($line =~/^DEBUG: query:/){ $get_q++; } elsif ($get_q and $line =~ /^DEBUG: /) { $query = $buffer; $buffer = ''; $get_q = 0; } if ($get_q) { $buffer .= $line; $buffer =~ s/^DEBUG: query://g; $buffer =~ s/\s+/ /g; } if (!$get_q and $line =~ /^\s+:total_cost\s+(\S+)/) { my $cost = $1; no warnings; $cost =~ s/([\d.]+)/$1/g; $q{$_}{cost} = 0 if ($q{$_}{cost} =~ /[^\d.]/); $q{$query}{cost} = $cost > $q{query}{cost} ? $cost : $q{$query +}{cost}; $q{$query}{tot} += $cost; push(@{$q{$query}{costs}},$cost); $q{$query}{cnt}++; use warnings; } $q{$query}{scan} = 'SEQ' if (!$get_q and $line =~ /^\s+{\s+SEQSCAN +/); $q{$query}{scan} = 'IDX' if (!$get_q and $line =~ /^\s+{\s+INDEXSC +AN/); $cnt++; print "Reading line: $cnt of $lines\r" if (!($cnt % 1000)); } print "\n Cleaning..."; foreach ( keys %q ) { if (/pg_/){ delete $q{$_}; next } #skip internal tables my $tot; foreach my $cost (@{$q{$_}{costs}}) { $tot += $cost; } $q{$_}{cost} = 0 if (!$q{$_}{cost} or $q{$_}{cost} =~ /[^\d.]/); $tot ||= 0; $q{$_}{cnt} ||= 0; if ($q{$_}{cnt}) { $q{$_}{avg} = $tot / $q{$_}{cnt}; } $q{$_}{avg} ||= 0; $q{$_}{tot} ||= 0; } print "\n DONE\n Sorting... "; my @srt_keys = sort { $q{$a}{$sort_fld} <=> $q{$b}{$sort_fld} } keys +%q; @srt_keys = @srt_keys[$#srt_keys-($show-1)..$#srt_keys]; print "\n"; print " Total Cost Avg IDX Query\n"; print "-------- -------- -------- --- ------->\n"; foreach (@srt_keys) { printf("%8s ",sprintf("%.3f",$q{$_}{tot})); printf("%8s ",sprintf("%.3f",$q{$_}{cost})); printf("%8s ",sprintf("%.3f",$q{$_}{avg})); print " $q{$_}{scan} $_\n"; } sub usage { print "@_\n" if (@_); print "plog [--sort=tot|cost|avg] [--show=1000] /path/to/logfile\n +"; print "\t--sort : sort results by tot(Total Time) cost(Max Cost) o +r avg(Average Cost)\n"; print "\t--show : show number of lines (default: 25)\n"; exit(); }
Some Sample Output:
Total Cost Avg IDX Query -------- -------- -------- --- -------> 138.780 5.140 5.140 IDX select description from products wher +e sku = '142-1007' 138.780 5.140 5.140 IDX select sale_price from products where + sku = '142-1007' 143.920 5.140 5.140 IDX select sale_price from products where + sku = '140-1028' 143.920 5.140 5.140 IDX select thumb from products where sku += '00024' 143.920 5.140 5.140 IDX select sku from products where sku = +'142-1009' 143.920 5.140 5.140 IDX select option_type from products wher +e sku = '140-1028' 149.060 5.140 5.140 IDX select gift_cert from products where +sku = '140-1028' 154.700 5.950 5.950 IDX select * from options where code = '1 +42-1007' 154.700 5.950 5.950 IDX select * from options where code = '1 +12-9083' 154.700 5.950 5.950 IDX select * from options where code = '1 +40-1028' 164.480 5.140 5.140 IDX select description from products wher +e sku = '140-1028' 185.040 5.140 5.140 IDX select sku from products where sku = +'142-1011' 231.300 5.140 5.140 IDX select sku from products where sku = +'142-1035' 233.100 3.150 3.150 IDX SELECT o_group,price FROM options whe +re sku = '142-1035' and price != '' 233.100 3.150 3.150 IDX SELECT o_group,price FROM options whe +re sku = '142-1030' and price != '' 246.720 5.140 5.140 IDX select sku from products where sku = +'gift-cert' 267.280 5.140 5.140 IDX select thumb from products where sku += '112-9083' 267.280 5.140 5.140 IDX select thumb from products where sku += '140-1028' 267.280 5.140 5.140 IDX select thumb from products where sku += '142-1007' 287.840 5.140 5.140 IDX select sku from products where sku = +'00024' 292.830 97.610 97.610 SEQ select * from products
| XP matters not. Look at me. Judge me by my XP, do you? |
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: PostgreSQL Query Performance Analysis
by aufflick (Deacon) on Nov 19, 2006 at 11:44 UTC |