実行計画を知ることで得られること
- 発行するクエリがどれくらいの時間で処理されるかわかる
- SQLのダメなところが見える
- 発行対象のテーブルがばかでかいテーブル(レコード数や行サイズ)の場合の検知
実行計画とは
postgresが算出した、一番時間がかからないクエリ実行手順のこと
一つのクエリ実行(結果)を出すための実現方法(手順)は多数存在する。postgres内部では対象のテーブルの状態(統計情報)を参照して、 実行時点で一番時間のかからないクエリ実行になる実現方法はなにか、という最適化問題を解いている。 このpostgresが算出した最適な実現方法(手段)をpostgresでは「実行計画」と呼んでいる。
実行計画の仕組み
- 発行するクエリを「ノード」というサブ実行単位に分割され、ツリー構造で表現する
- ツリーの葉から根に向かって順次実行
ノードの種類は大きく三種類
- スキャンノード(テーブル内の情報を探索する)
- 結合ノード(文字通りテーブルの結合)
- 加工ノード(文字通り)
ノード
1. スキャンノード(テーブル内の情報を探索する)
- seq scan
- index scan
シーケンススキャンの場合、テーブルのレコード1行1行を読み込んで、条件式(WHERE)などがあればそれを逐一実行する
インデックスが貼られていれば、条件式を評価する前に、indexでレコードを絞ってから、条件式を評価する。シーケンススキャンをしていれば、条件式の実行はレコード数分だが、インデックスが貼られていれば一回ですむ可能性もある。
つまり一般的には処理が早い。
2. 結合ノード(文字通りテーブルの結合)
三種類ある
-
入れ子ループ結合
- 外側テーブルの1行に対して内側テーブルの全レコードをなめる素直な方法
- みたからに時間はかかりそうだが、外側テーブルがレコード少ない&内側テーブルにシーケンス貼ってある 場合はかなり高速らしい
-
ハッシュ結合
- まず内側テーブルの結合キーに対してハッシュを算出
- 算出したハッシュはメモリ上に置かれる、そのためメモリがないと遅くなる
-
マージ結合
- 両方のテーブルを結合キーでソートしてその順番で評価する
- 事前にソートするのでそのオーバーヘッドはある、が結合キーがそもそもソートしていたらうまく動いてくれる
3. 加工ノード(文字通り)
- 文字通り、とかいたもののイメージはわいていない。。。
参考文献
- 内部構造から学ぶPostgreSQL 設計・運用計画の鉄則