$shibayu36->blog;

株式会社はてなでエンジニアをしています。プログラミングや読書のことなどについて書いています。

「内部構造から学ぶPostgreSQL」読んだ

最近PostgreSQLに発行するクエリのパフォーマンスチューニングや、PostgreSQLの調査を行うことが多かったので、ちゃんと学ぼうと思って読んだ。

内部構造から学ぶPostgreSQL 設計・運用計画の鉄則 (Software Design plus)

内部構造から学ぶPostgreSQL 設計・運用計画の鉄則 (Software Design plus)

この本はその名の通り、内部処理がどのように行われているかを紹介しながら、PostgreSQLの概念やパフォーマンスチューニングの勘所、統計情報の見方などなどを教えてくれる。特にPostgreSQLを自分で運用している人にはおすすめな本だろう。

アプリケーションエンジニアとして、PostgreSQLの運用自体はしていないけど、アプリケーションからクエリを書いている自分にとっては、以下の場所が非常に面白かった。

  • 6.6 性能を踏まえたインデックス定義
  • 12.2 正常動作の監視
    • pg_stat_activityなど、データベースの統計情報を知る術や、現在の発行しているクエリの様子を知る術を教えてくれる
  • 15章 実行計画の取得/解析
    • EXPLAINの見方を詳しく教えてくれる

特に15章はかなり参考になった。PostgreSQLのEXPLAINは、MySQLのときのEXPLAINとは全く出力が違ったので全く読めてなかったのだけど、これで読めるようになったなーという感じ。ついでに結構PostgreSQL側がいろんなことをやっているのだなということも知ることができた。



さて、以上のような面白いところはあったけれど、逆にもうちょっと基本的な、PostgreSQLで使える機能とか、あとインデックスの使われ方みたいなところは知ることが出来なかったなと思った。この辺学ぶには何を見ると良いのかな〜。

読書ノート

- PostgreSQLのプロセス構成 430
    - マスタサーバ
    - ライタ: 共有バッファの内容をデータファイルに書き出す
    - WALライタ: WALバッファの内容をWALファイルに書き出す
    - チェックポインタ: すべてのダーティページをデータファイルに書き出す
    - 自動バキュームランチャ
    - 自動バキュームワーカ
    - 統計情報コレクタ
    - バックエンドプロセス: クライアントから接続要求に対して起動され、クエリを処理する
- PostgreSQLのメモリ構成 463
    - 共有バッファ: テーブルやインデックスのデータをキャッシュ
    - WALバッファ
    - 空き領域マップ
    - 可視性マップ: テーブルのデータが可視であるか否か
- テーブルファイルは、複数の8192バイトの「ページ」によって構成 530
- インデックスファイルもテーブルファイルと同様に8192バイト 530
- TOASTファイル: テーブル内に長大な行(2KB以上とか)を格納する場合に生成される特殊なファイル 530
- 設定項目が反映されるタイミング 605
    - SET文実行時
    - SIGHUPシグナル受信時
    - 起動時
    - pg_settingsビューのcontext列の値で確認可能
- チェックポイントは、PostgreSQLがクラッシュしたときに、どの箇所からリカバリ処理を行うのかを示すポイントになる 770
- バキュームは、データファイルやインデックス内の不要領域を再利用可能にする 787
- アナライズはクエリ実行に利用する統計情報を収集しpg_statisticを更新する処理 787
- 問い合わせ処理はパーサ、リライタ、プランナ、エクゼキュータという風に実行される 827
- PostgreSQLは追記型アーキテクチャ 962
- 主キーと一意性制約が定義された列には暗黙のB-treeインデックスが作成される 1088
- 外部キーには暗黙的なインデックスが設定されない 1105
- PostgreSQLに対して更新要求があった時、まず更新のログをWALバッファに書き込む 1246
- 複数列インデックスがなくとも、ほとんどの場合検索条件として使われる可能性がある個々の列に対して別々のインデックスを作成すれば十分なケースが多い 1408
- 関数インデックス 1408
- 部分インデックス: 特定の条件を満たす行の値のみインデックス化の対象にできる 1418
- PostgreSQLの稼働統計情報ビュー 1598
    - pg_stat_database, pg_statio_user_tables, pg_statio_user_indexes, pg_stat_activity
- PostgreSQLの正常動作の監視 2506
- Index Only ScanはVisibility Mapを確認する形で実現されている 2756
    - EXPLAINのBUFFERSオプションを付けるとHeap Fetchesの値で分かる
- EXPLAINのBUFFERSオプションを付与すると、共有バッファから読み込んだページ数とディスクから読み込んだページ数を追加で表示する 2860
- EXPLAINの実行計画の読み方 2974~ ☆
- データ結合の実行計画 3015 ☆
    - Nested Loop, Hash Join, Merge Join
- 結合時は外側テーブルと内側テーブルの順序も性能に大きな影響を与える 3025
- Nested Loopは二重ループ。外側テーブルの行数が少なく、内側テーブルにインデックスが貼っていると、他の二つより高速に動く 3026
- ハッシュ結合は、内側テーブルの結合キーでハッシュを作成し、ハッシュと外側テーブルの結合キーを評価する 3026
    - ハッシュを作成するためにまず、内側テーブルをスキャンし、その後外側テーブルをスキャンするという動作になる
    - ハッシュがメモリに収まるサイズの場合有効
- 実行計画の処理コストの見方 3086