なからなLife

geekに憧れと敬意を抱きながら、SE、ITコンサル、商品企画、事業企画、管理会計、総務・情シス、再び受託でDB屋さんと流浪する人のブログです。

PostgreSQLのpsqlで実行時間だけ欲しい場合

用途

時間計測したいけど、結果の行表示とか余計なものは全くいらない、ってケースありますよね。性能検証やってるときとか。

何百行何千行も取れるようなSQL流すと、表示するのも萎える。
pager有効だと「--More--」って出て止まる。これは「q」で残りの表示はスキップできるけど、それもめんどくさい。
pager無効にすれば余計な操作はいらなくなるけど、表示処理が重いし。

結論

psqlでログインして「\timing」で実行時間表示モードをONにした後、以下を実行します。

その1:メタコマンド「\g」を使って、/dev/nullにリダイレクトする。
SELECT ...(任意のクエリ) \g |> /dev/null

Windowsコマンドプロンプトだと、Nullへのリダイレクトは「>nul」、Powershellだと「> $null」が該当するらしいのですが、これ使うと「The syntax of the command is incorrect.」というメッセージが出ます。
でも、取れる時間自体は、実際にかかった時間が取れているみたいです。(Linux上のpsqlで実行したときと同等の時間が表示されていました)

その2:メタコマンド「\o」で、出力先を 「/dev/null」にする。

その1で十分に満足しつつ、追加でちょっと調べてたら、たまたま見つけました。
PostgreSQLでSQLファイルの実行速度を計測する - Qiita


リンク先は、実行するSQLをファイルに書いて取り込むようにしていますが、出力結果を「\o」でコントロールするだけで、実行するSQL自体はpsql内で直接書いて構いません。

この方法、Windowsコマンドプロンプトなら「\o nul」、Powershellなら「\o $null」で、エラーメッセージなしで時間が取れます。

結果を元の表示に戻したい場合は、OS共通で「\o (引数なし)」を実行するだけです。

これはすごい。

驚き

psql パラメータいろいろ -c "任意のSQL" > /dev/null」じゃなくて、psqlの中から実行してるのにパイプ+リダイレクトで/dev/nullっていう、この構文のキモさよ。

じゃなくて、
「\g」方式も、「\o」方式も、psqlが豊富に備えているメタコマンドなんですよね。
なので、ちゃんとドキュメントに書いてあるんですよね。

mysql畑から来た人としては、mysqlではできない(少なくとも知らない)ヤツなので、その頭のままPostgreSQLにやってくると「ドキュメント調べてみよう、何か書いてあるかもしれない」っていう頭に切り替わらない。

Oracleでは「set autotrace traceonly」すれば、SQLを実行したあとに処理時間と実行計画を表示しつつクエリ結果行は出なくなるけど、実行計画取るのがメインだから大きいSQLだと実行計画がダラダラ表示される。*1


また、ドキュメントの該当箇所にたどり着けたところで、「\g」メタコマンドから「|> /dev/null」につなげようという発想にたどり着けるかは、また別のセンス?が必要。


そういえば、先日の「MySQLの学び方」のイベントでもyokuさんが「ドキュメントを読もう」って言ってたよね。マジで何を学ぶにもドキュメントは大事。
https://speakerdeck.com/yoku0825/mysqlwoxue-buji-shuDevelopersNight 01 : ゆるく学ぶMySQL #GMODev - Togetter



余談

MySQLでコレに該当する方法は今の所は見当たらなくて、ググるLinuxのtimeコマンドを使う方法がヒットします。出力形式の違いや、都度ログインなので認証処理のオーバーヘッド等が加算されますけど、(Linuxなら)汎用的に使える方法ですね。

ご協力ありがとうございました。

今回は、Twitterでtjtakahashiさんから教えていただいた方法が私の求めていた形のものでしたが、kkaigaiさんとかmasahiko_sawadaさんとかtzkbさんとかsoudai1025さんとかyoku0825さんとかマジですごい人達からリプがついてて、軽くビビりました。感謝感激です。






こんなとき、誰のどの本を推しておけばよいのかよくわからないけど、「実はマニュアルにそれらしきことは書いてあった」>「基本に立ち返ろう」ってことで、入門書で一番新しそうなヤツをおいておきます。

*1:PostgreSQLでも同じアプローチで「explain analyze」が実行計画取るのにウラでSQLを実際に走らせることができる