(これは PostgreSQL Advent Calendar 2014 参加エントリです。)
『内部構造から学ぶPostgreSQL – 設計・運用計画の鉄則』 (技術評論社, 2014) という本がとても良いです。 まだ全部を読めたわけではないのですが、それでも良い本であることがよくわかりました。 PostgreSQL を使う人にはぜひ読んで欲しいと思うので、紹介します。
どんな本か?
この本は、PostgreSQL について内部構造から解説してくれた、中級者向けの本です。
PostgreSQL には立派なマニュアルがついてるんですが、これがあんまり分かりやすくないんですよね。 なんというか、分かっている人向けの説明ばかりで、分かってない人が読んでも分かるようにはならない説明、という感じ。 機能は網羅されているからリファレンスとしてはとても役に立ちますが、あのマニュアルを読んで PostgreSQL を勉強しろと言われたら、軽い絶望感を覚えます。
それと比べると、本書は PostgreSQL の仕組みを分かりやすく説明してくれています。 なんといっても、文章が分かりやすい! リファレンスマニュアルと違って、読んで頭に入ってくる文章です。素晴らしい。 またデータ構造や動作イメージを図で説明しているので、文章だらけのリファレンスマニュアルよりも分かりやすいです。
ただし入門書ではないので初心者にはとてもお勧めできません。 しかし仕事で PostgreSQL を触っている人なら、読むととても勉強になるはずです。
本書は 4 部 16 章から構成されています。
- Part 1 基本編 … PostgreSQLのアーキテクチャについての説明です。サーバのプロセスやメモリや設定ファイルについて書かれています。SQL がどう実行されるか (構文解析→実行計画作成→実行) や、トランザクションの分離レベル (READ COMMITTED とか REPEATABLE READ) とかの説明もあります。
- Part 2 設計/計画編 … テーブル設計や物理設計の説明です。データ型の実装の詳細とか、テーブルファイルとインデックスファイルの仕組みとかが解説されています。またバックアップや監視についても説明されていますが、これは次の「運用編」に組み込んだほうがいいように思いました。
- Part 3 運用編 … この章はまだ読めてないんですが、目次を見ると、バックアップや死活監視や DB メンテナンスの説明があります。それに加えて、レプリケーションやホットスタンバイの話題もこの章に含まれています。ここら辺は自分の不得意分野なので、時間をかけて勉強したいです。
- Part 4 チューニング編 … パフォーマンスチューニングについての章です。SQL のチューニングと、設定パラメータによるチューニングの両方が解説されています。実行計画作成におけるコスト見積もりの計算式がとても勉強になりました。
著者 (3 名) は NTT ソフトウェアの方々です。 皆さん、えらい実装に詳しいんですね。 たとえば 85 ページでは、Interval 型のデータサイズについてこんな注釈がありました。
PostgreSQL 文書では 12 バイトとなっているが、ヘッダファイルやテーブルファイルのダンプを参照すると 16 バイトの領域を確保していると考えられる
著者の方々がちゃんとソースコードを読んでいる証拠ですよね。 そりゃ詳しいわけだわ。 個人的に NTT D○C○M○ と NTT 出たー が嫌いなんですが (イヤな思い出しかない)、NTT ソフトウェアは尊敬することにします。
書かれてないこと
本書のタイトルにあるように、これは PostgreSQL の内部構造を知り、運用に活かすための本です。 PostgreSQL の入門書ではないので、インストール方法とか、SQL の文法とかは書かれてないです。 そういうのは他の書籍をあたってください。
また本書は中級者向けだとは思いますが、再帰 SQL や Window 関数や hstore の使い方が書いているわけでもないです。 そういうのを知りたい人は、頑張ってリファレンスマニュアルを読みましょう。
(explain の出力が) 読める、読めるぞ!
個人的にいちばん参考になった第 4 部を詳しく紹介してみます。
SQL のチューニングでは、explain を使って実行計画を確認します。 しかし、explain の出力結果を理解するのは難しい。 リファレンスマニュアルで explain の章 を読んでも、よくわからんです。 さっきも書きましたが、リファレンスマニュアルは「分かってる人向け」の文章になっていて、分かってない人が分かるようになるには向かないと思います。
本書では第 4 部で explain の読み解き方が、読んで分かる文章で説明されています。 今までは SeqScan がないかとか、期待したインデックスが使われているか、ぐらいしかチェックしてなかったんですが、本書のおかげでコスト見積もりの部分とかがよく分かるようになりました。 今まで、見積もりコストの値にはなぜ単位がないんだろうと思ってましたが、あるコストを 1 としたときの相対値として計算されてるんですね。 そりゃ単位がないよなー、と納得できました。
コストの計算式も、具体例で説明されています。 たとえば p.252 から引用しますが、こんな設定とテーブルがあったとして、
1ページあたりの読み込みコスト (seq_page_count): 1.0
1行あたりの処理にかかるCPUコスト (cpu_tuple_cost): 0.01
--------
テーブル名: random_t
ページ数 (relpages): 4425
行数 (reltuples): 1000000
explain の出力結果が次のようだとします。
=# EXPLAIN SELECT * FROM random_t;
QUERY PLAN
-----------------------------------------------------------------
Seq Scan on random_t (cost=0.00..14425.00 rows=1000000 width=4)
このときコストが「0.00..14425.00」になっているのは、次のような計算式だからだそうです。
始動コスト = 0
総コスト = ディスクI/Oのコスト + データ処理のCPUコスト
= (seq_page_count * replpages) + (cpu_tuple_cost * reltuples)
= (1.0 * 4425) + (0.01 * 1000000)
= 4425 + 10000
= 14425
ほんとだ、explain の出力結果と一致している!面白いですね。
とはいえ、explain の出力結果が読めるようになると、
「SQL ってさー、処理の順序は気にせずに宣言的に書けばいい、っていうのが売りだよねー? でもチューニングするときは explain の結果を見ながら join や filter の順番を気にしないといけないんでしょ? 言ってることとやってることが違くね?」
という、SQL に対する根源的な疑問が抑えきれなくなります。 残念ながら、その解答は本書には書かれてないようです。
要望をいくつか
さて、本書がとても良く書かれてあることは紹介した通りです。 しかし、いくつか残念な点があります。
誤字脱字が多い
まず、誤字脱字が多いです。 たとえばさっきの p.252 には、こんな一文があります。
コストは次の次の計算式で求められます。
編集者、仕事しろよ…
まあ日本語の間違いは、どう直せばいいのか推測できるのでまだいいです。 問題は、SQL や図での間違いですよね。 これを間違われると、なかなか気付きにくい。
たとえば p.109 の図 6-5 には
UPDATE item SET id = 200 where id = 102
という SQL があるんですが、図の内容から判断するとこれは「SET id = 105」だと思います。 これは自分でも分かる範囲だからいいですが、自分がよく分かってない箇所で SQL や図の間違いがあると、気付くことなくそのまま鵜呑みにしてしまうでしょう。
あるいは p.74 の図 4-9 では、「data」とすべきが全部「date」となっているのはまあ分かるからいいとして、トランザクション A の XID は、1003 ではなく 1002 だと思うんだけど…いまいち自信がない。 こういう、説明の核となるところで間違いがあると、読者としてはつらい。
正誤表があるかなと思ってググってみましたが、今のところ見つかりませんでした。 技術評論社の本書のページに正誤表が載るといいな。
あとで解説される用語が先に登場する
たとえば p.102 に「FILLFACTOR」という用語が説明なしに使われており、その「FILLFACTOR」の詳しい解説は p.110 にあります。 まあ本書を読むような人は FILLFACTOR ぐらい聞いたことあるだろう、という前提なのかもしれませんが、ここは p.102 のほうで「FILLFACTORについては p.110 で説明します」という脚注を入れておくだけで、ずいぶん読者の助けになると思います。
ほかにも、たとえば p.36 に「TOAST ファイル」の説明がありますが、じゃあ「TOAST」って何よ? というのは p.94 まで読まないとわかりません。 これもやはり p.36 のほうに「TOAST については p.94 を参照のこと」という脚注が入ってほしいなと思いました。
それとは少し違いますが、関連する内容が別々のページで説明されていれば、互いのページへのリンクがあるといいなと思います。 たとえば関数インデックスや部分インデックスの説明が p.117~118 と p.273~274 にあるのですが、こういうのはそれぞれのページで「xxページでも解説してるので参照してください」という脚注があるとうれしいです。
SQL チューニングの内容をもっと増やして欲しい
これはもう個人的な希望でしかないんですが、SQL チューニングの章はあと 20 ページぐらい増やして欲しい!
たとえば「非相関サブクエリを使って join を減らす」とか、「with 句を使って内部の実行順序を強制指定する」とか、「array_agg() を使って一対多での取得行数を減らす」とか、そういうテクニックをもっと知りたいです (邪道かもしれないけど)。 あるいはチューニングとはちょっと違うけど「generate_series() を使って日付の歯抜けを防ぐ」とか「upsert (データがあれば update、なければ insert) 」とか、PostgreSQL の機能を使い倒すようなのを希望します。
まあ、世間的には sharding のような scalability についての話題のほうが需要が高そうですが。
まとめ
『内部構造から学ぶPostgreSQL – 設計・運用計画の鉄則』 という本を紹介しました。 入門書ではないので初心者には向きませんが、PostgreSQL の仕組みを知りたい中級者にはうってつけでしょう。 内容は高度なので、一度で理解しようとせず、何度が読み返すのがいいと思います。
とはいえ、この本を読んでも上級者への道はまだ遠いんだろうなあ、と思います。 これを読んだら、次は『PostgreSQL全機能バイブル』(鈴木啓修 著、技術評論社、2012) とか、あるいは英語が苦手でなければ『PostgreSQL 9.0 High Performance』とかを読むといいらしいです。 特に後者は Amazon のカスタマーレビューで絶賛されてるようだし、英語が苦手でないどなたかチャレンジしてください。
あ、もちろんリファレンスマニュアルを読むのもいいと思いますよ。 その先は…ソースコードリーディングですかね。 200万行を軽く超えてるそうですが。
著者の一人として大変ありがたく思います。
誤字については・・・すいません・・・。
正誤表も編集さんと相談かなあ・・。
こちらこそ、たいへんな良本をありがとうございます。
ざっと目に付いた誤字をまとめておきました。
https://gist.github.com/kwatch/3503849e3a2fd588322d
正誤表は、技評社が書籍ごとに用意しておくのが望ましいですよね。
著者の一人として、大変嬉しいコメントです。
ありがとうございます。
誤字の件は・・・すいません。