大量のデータを投入したら、analyzeしよう。
先日、JDBC経由でPostgreSQLのcopyコマンドで大量のデータ(数千万)を投入し、
すぐselectしたら、selectが終わらないことが数回ありました。
通常なら、同じデータ量でも1分以下で終わっていたので、おかしかったです。
調査のため、該当select文を抽出し、psqlコマンドで動かしてみたら、同じく実行が終わりませんでした。
select文から結合するテーブルを減らしてみたりいろいろやってみましたが、同じでした。
最後にorder by句を削除してみたら、なんとselectの結果が通常(1分以下)のように返ってきました。
もしかしたらと思って、vacuum analyzeを実行して、再度order byを付けてselect文を実行したら、
見事に数秒後、結果が返ってきました。
データの投入(insert)なら、何も気にする必要はないと思いましたが、違いましたね。
おそらく(しかし、ほぼ確実のような...)大量データの投入後、DBMSの統計情報の更新処理がたまたま間に合わなかったのではないかと思います。
発生する頻度は少ないですが、いったん発生すると、大変なので、
大量データを投入した直後はvacuum analyzeやanazlyzeを実行しておいた方がいいでしょう。
insertだけなら、vacuumは不要でanalyzeだけでいいと思いますが、
(fullでない)vacuumはそんなに遅い処理(私のローカルでは1-2秒ぐらい)ではないですし、
将来updateやdeleteが追加されるかもしれませんので、vacuum analyzeにしてもいいかなと思います。
もちろん、これはバッチ処理での話です。
リアルタイム系やトランザクション系ではNOSQLや別の工夫が必要でしょう。