PostgreSQLでSQL毎の実行にかかった時間をログに残す方法
postgresql.conf に以下を設定します。
log_min_duration_statement = 0
これは指定ミリ秒以上時間がかかったSQL文をかかった時間と一緒にログに残すようにします。 0を設定するとすべてのSQL文をかかった時間とともにログに出力します。
※注意
この設定と log_statement を同時に設定すると、log_statement の設定によるSQL文のログとlog_min_duration_statement によるSQL文のログがそれぞれ出力されてしまう為、同じようなログが2重に出てしまいます。なので log_min_duration_statement=0 を使う場合は log_statement は無効にするべきです。
duration_statementを含んだログファイルを解析して統計情報を表示するスクリプト
以下のような Perl スクリプトを作成してログをパイプで流すことで、各SQL文毎の実行回数・平均時間・最大時間・合計時間がタブ区切りで出力されるので、ボトルネックを探すのに便利です。
analyze-log_min_duration_statement.pl
#!/usr/bin/perl use strict; my %count = (); my %sum = (); my %max = (); while(my $line = <STDIN>) { next until($line =~ / duration: ([0-9\.]+) ms\s+statement: (.*)$/); my $msec = $1; my $statement = $2; $count{$statement}++; $sum{$statement} += $msec; if($max{$statement} < $msec) { $max{$statement} = $msec; } } foreach my $statement (keys %count) { my $c = $count{$statement}; my $s = $sum{$statement}; my $m = $max{$statement}; my $a = $s / $c; print "$a\t$m\t$c\t$s\t$statement\r\n"; }